Felix Dombek
Felix Dombek

Reputation: 14356

C++ function pointer syntax

I know that generally, a function pointer is declared like this:

 void __stdcall my_func(int i) {} // for assigning

 void (__stdcall * my_ptr)(int) = &my_func;

Now I had several functions which take a function pointer as their argument:

 void calling_func(void (__stdcall * callback)(int)) { *callback(1); }

In the header file, I just removed the name of the thing:

void calling_func(void (__stdcall *)(int));

and voilá, that worked ... and got me thinking: If that is a complete type declaration, couldn't one use the normal TYPE NAME = VALUE syntax also for function pointers?

I tried to declare:

 ( void (__stdcall *)(int) ) callback = &my_func;

and it also compiles! Why isn't this used more often? Are there flaws with this notation? To me it seems that it would greatly ease the use of function pointers ... also in typedefs, for example: generally it's typedef OLDNAME NEWNAME, just with function pointers it's this weird inside-out syntax where the new name is actually in the middle of the whole expression. Let alone the notation for functions returning a function pointer ...

Upvotes: 3

Views: 2744

Answers (3)

ssube
ssube

Reputation: 48247

I much prefer typedefing my function pointers, and have yet to have problems with it.

Typedef, if I understand it correctly, doesn't so much make a new type as an alias to the other one (which is why size_t and unsigned int can be used interchangeably without compiler complaints, for example). So, for function pointer types you use often, typedefs make them a lot easier to work with.

For function pointer typedefs, the syntax goes:

typedef IObject *    (*CreateFunc )(int, Core *);

With the desired type name on the inside (not much different from what you're doing now). You can specify most function modifiers (__stdcall, __declspec, etc), they come just inside the parentheses before the * name.

You can call, assign and get the value of these quite easily, as well as converting them to void * for passing (when the type is unknown).

Upvotes: 1

unwind
unwind

Reputation: 399763

That is not a declaration, it's a cast of callback, which is then assigned to.

Are you sure you didn't have a pre-existing declaration in scope?

Upvotes: 4

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385104

Doesn't compile for me. AFAIK it's not valid C++.

You can fake it, though!

template <typename T>
struct identity {
   typedef T type;
};

identity<void(*)(int)>::type callback = &my_func;

Or use something like boost::function (or std::function) for the ultimate wins.

Upvotes: 4

Related Questions