244

I'd like to write this

typedef void (*FunctionPtr)();

using using. How would I do that?

1
  • 7
    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. Commented Jun 16, 2016 at 21:01

5 Answers 5

272

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.

Sign up to request clarification or add additional context in comments.

15 Comments

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<void()>;
|
69

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

2 Comments

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.
17

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.

Comments

12

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

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

4 Comments

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...<br/> Try using FunctionPtr: using namespace std; #include <iostream> 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(); }
8

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.