ChatGPT解决这个技术问题 Extra ChatGPT

How do I typedef a function pointer with the C++11 using syntax?

I'd like to write this

typedef void (*FunctionPtr)();

using using. How would I do that?

very confusing indeed, especially because function pointer identifiers usually resided in the middle of a typedef statement and move to the front using using. At least that's where I'm lost.

D
David G

It has a similar syntax, except you remove the identifier from the pointer:

using FunctionPtr = void (*)();

Here is an Example

If you want to "take away the uglyness", try what Xeo suggested:

#include <type_traits>

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

And here is another demo.


Dang, I hoped it would take away the ugliness :(
@rubenvb: using FunctionPtr = AddPointer<void()>; ;)
It's possible to use template type aliases to further clean up add_pointer<void()>::type: Using the suggestion here: groups.google.com/a/isocpp.org/d/msg/std-proposals/xDQR3y5uTZ0/… you can write pointer<function<void>>.
These type aliases change the type syntax from obscure, inside-out syntax to a simple left-to-right syntax, which largely eliminates the need for custom typedefs for specific APIs that make it easier to write that API's compound types.
In C++14, you will be able to write: using FunctionPtr = std::add_pointer_t;
V
Vadim Goryunov

The "ugliness" can also be taken away if you avoid typedef-ing a pointer:

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

http://ideone.com/e1XuYc


This is an interesting approach, though I might be worried I'd forget the * later and get confusing errors.
This definitely is the nicest version presented here. Thank you. And I prefer seeing a pointer, as it is a function pointer after all.
A
Andrew Tomazos

You want a type-id, which is essentially exactly the same as a declaration except you delete the declarator-id. The declarator-id is usually an identifier, and the name you are declaring in the equivilant declaration.

For example:

int x

The declarator-id is x so just remove it:

int

Likewise:

int x[10]

Remove the x:

int[10]

For your example:

void (*FunctionPtr)()

Here the declarator-id is FunctionPtr. so just remove it to get the type-id:

void (*)()

This works because given a type-id you can always determine uniquely where the identifier would go to create a declaration. From 8.1.1 in the standard:

It is possible to identify uniquely the location in the [type-id] where the identifier would appear if the construction were a [declaration]. The named type is then the same as the type of the hypothetical identifier.


L
Leo Goodstadt

How about this syntax for clarity? (Note double parenthesis)

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

What do the double parenthesis mean in this context? A reference to a function pointer?
Your FunctionPtr is not a function pointer, but decltype(&f) is, see here.
@1234597890 FunctionPtr is a non-const lvalue reference to type 'void ()'
@rubenvb: You are right. It is not a function pointer but a lvalue reference to the function (type). Which is why static_assert fails...
Try using FunctionPtr: using namespace std; #include void do_f() { cerr << "what?\n"; } void f(); using FunctionPtr = decltype((f)); using FunctionPtr2 = decltype(&f); // Doesn't work //using FunctionPtr3 = decltype(f); int main() { FunctionPtr ff = do_f; ff(); FunctionPtr2 ff2 = do_f; ff2(); }
S
Silvester

Another approach might using auto return type with trailing return type.

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

This has the arguable advantage of being able to tell something is a function ptr when the alias begins with "auto(*)" and it's not obfuscated by the identifier names.

Compare

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

with

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

Disclaimer: I took this from Bean Deane's "Easing into Modern C++" talk