如何使用C ++ 11使用语法typedef函数指针?


171

我想写这个

typedef void (*FunctionPtr)();

使用using。我该怎么办?


2
using确实非常conf ,尤其是因为函数指针标识符通常位于typedef语句的中间,并使用移到最前面using。至少那是我迷路的地方。
starturtle

Answers:


180

它具有相似的语法,只是您从指针中删除了标识符:

using FunctionPtr = void (*)();

这是一个例子

如果您想“摆脱丑陋”,请尝试Xeo的建议:

#include <type_traits>

using FunctionPtr = std::add_pointer<void()>::type;

这是另一个演示


25
Dang,我希望它能消除丑陋:(

10
@rubenvb:using FunctionPtr = AddPointer<void()>;;)
Xeo

2
可以使用模板类型别名进行进一步清理add_pointer<void()>::type:使用此处的建议:groups.google.com/a/isocpp.org/d/msg/std-proposals/xDQR3y5uTZ0/…您可以编写pointer<function<void>>
bames53 2013年

5
这些类型别名将类型语法从模糊的,由内而外的语法更改为简单的从左到右的语法,从而在很大程度上消除了对特定API的自定义typedef的需要,从而使编写该API的复合类型更加容易。
bames53

10
在C ++ 14中,您将能够编写:using FunctionPtr = std :: add_pointer_t <void()>;
Andrzej

46

如果避免键入指针,则也可以删除“丑陋”:

void f() {}
using Function_t = void();    
Function_t* ptr = f;
ptr();

http://ideone.com/e1XuYc


这是一种有趣的方法,尽管我可能担心我会忘记*后面的内容并得到令人困惑的错误。
Apollys支持Monica's

这绝对是这里介绍的最好的版本。谢谢。而且我更喜欢看到一个指针,因为它毕竟是一个函数指针。
皮埃尔

13

您需要一个type-id与声明完全相同的声明,只是删除declarator-id。在declarator-id通常是一个标识符,和名字你在equivilant声明宣布。

例如:

int x

declarator-idx这样只是将其删除:

int

同样地:

int x[10]

删除x

int[10]

例如:

void (*FunctionPtr)()

这里declarator-idFunctionPtr。因此只需将其删除即可type-id

void (*)()

这是可行的,因为给定a时,type-id您始终可以唯一地确定标识符在哪里创建声明。从标准的8.1.1开始:

如果构造是[声明],则可以唯一标识[type-id]中标识符将出现的位置。然后,命名类型与假设标识符的类型相同。


9

为了清晰起见,该语法怎么样?(注意双括号)

void func();
using FunctionPtr = decltype((func));

1
在这种情况下,双括号是什么意思?甲参考一个函数指针?
0x499602D2 2013年

5
FunctionPtr不是函数指针,而是decltype(&f),请参见此处
rubenvb

@ 1234597890 FunctionPtr是对'void()'类型的非常量左值引用
Leo Goodstadt 2013年

@rubenvb:你是对的。它不是函数指针,而是对函数(类型)的左值引用。这就是为什么static_assert失败的原因... <br/>尝试使用FunctionPtr:使用命名空间std; #include <iostream> void do_f(){cerr <<“什么?\ n”; } void f(); 使用FunctionPtr = decltype((f)); 使用FunctionPtr2 = decltype(&f); //无效//使用FunctionPtr3 = decltype(f); int main(){FunctionPtr ff = do_f; ff(); FunctionPtr2 ff2 = do_f; ff2(); }
Leo Goodstadt

1

另一种方法可能使用自动返回类型和尾随返回类型。

using FunctionPtr = auto (*)(int*) -> void;

当别名以“ auto(*)”开头并且不会被标识符名称混淆时,这可以说是函数ptr的优点。

比较

typedef someStructureWithAWeirdName& (FunctionPtr*)(type1*, type2**, type3<type4&>);

using FunctionPtr = auto (*)(type1*, type2**, type3<type4&>) -> someStructureWithAWeirdName&;

免责声明:我是从Bean Deane的“轻松进入现代C ++”演讲中获得的

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.