In general, if you are not using a cast, you should trust g ++.
Although it is true that none of the types of functions you are talking about can be exported for use inside C, this is not what you are asking for. You ask what functions you can pass as a function pointer.
To answer what you can convey, I think it is more constructive to understand that you cannot pass. You cannot pass anything that requires additional arguments not explicitly specified in the argument list.
So, non-static methods. They need an implicit "this". C will not know to pass it. Again, the compiler will not allow you.
No lambda capture. They require an implicit argument with the actual lambda body.
What you can pass are pointers to functions that do not require an implicit context. In fact, you went ahead and pointed them out:
- Function pointer. It does not matter if it is a standard function or a template if the template is fully enabled. It's not a problem. Any syntax you write that leads to a function pointer will automatically fully resolve the pattern.
- Does not capture lambda. This is a special work introduced by C ++ 11 when it introduced lambda. Since this is possible, the compiler performs the explicit conversion necessary to execute it.
- Static methods. Since they are static, they do not skip implicit
this , so they are fine.
The latter continues to expand. Many C callback mechanisms get a function pointer and void * opaq. The following is a standard and fairly safe possibility of using them with the C ++ class:
class Something { void callback() {
And then do:
Something something; register_callback(Something::exported_callback, &something);
Edited to add: The only reason this works is that the C ++ calling convention and the C calling convention are identical when implicit arguments are not passed. There is a difference in name manipulation, but it doesn’t matter when you pass a pointer to a function, since the only purpose of name manipulation is to allow the linker to find the correct address of the function.
If you tried this trick with a pending callback, for example, a standard call to stdcall or pascal, this scheme would fall on his face.
This, however, is not unique to static methods, lambdas functions, and templates. Even the standard function does not work under such circumstances.
Unfortunately, when you define a pointer to a stdcall type, gcc ignores you:
#define stdcall __attribute__((stdcall)) typedef stdcall void (*callback_type)(void *);
leads to:
test.cpp:2:45: warning: 'stdcall' attribute ignored [-Wattributes] typedef stdcall void (*callback_type)(void *);