I am trying to take a pointer to an instance of function template and cast it to void*:
#include <stdio.h>
void plainFunction(int *param) {}
template <typename T>
void templateFunction(T *param) {}
int main() {
void *addr1=&plainFunction; //OK
void *addr2=&templateFunction<int>; //Compile error
}
I get the following error (in Visual Studio 2008)
main.cu(10) : error C2440: 'initializing' : cannot convert from 'void (__cdecl *)(T *)' to 'void *'
Context does not allow for disambiguation of overloaded function
Why is it happening? Function templateFunction
(for concrete type T=int
) is not overloaded. It is possible to deduct which instance of the function I am refering to.
If I replace the erroneus line with:
void (*foo)(int*)=&templateFunction<int>;
void *addr2=foo;
It compiles without a problem.
Thank you!
Update:
When normal pointer void*
is replaced by dummy function pointer void(*)()
, as suggested by James (thank you), it makes the error go away:
void (*addr1)()=(void(*)())&plainFunction;
void (*addr2)()=(void(*)())(&templateFunction<int>);
However, if the error was caused by casting a function-pointer to a normal pointer, the compiler should complain in both cases. It does not however, so I continue to assume that it is correct at least for this compiler. If I am not mistaken, the standard just says that function pointers don't have to be represented like normal pointers, but it does not forbid that.
Both are technically wrong: in C++, you can't convert a function pointer to a void*
.
Pointer-to-function types (like void (*)(int*)
here) are a completely different class of types than pointer-to-object types (like void*
here).
Visual C++ allowing the conversion at all (e.g. in void* addr1 = &plainFunction;
) is a language extension (compiling with the /Za
flag, which disables language extensions, causes both lines to be rejected).
The error is a bit misleading, for sure, though some other compilers are equally unhelpful (Comeau reports "error: no instance of function template "templateFunction" matches the required type").
Compiler should generate error in both cases. Function pointers are not convertible to void
* according to the Standard §4.10/2 since functions are not objects (§1.8/1). Visual Studio 2008 allows this as an extension, check this bug.
Use typedef
to avoid misunderstanding:
typedef void(func)(int*); // declare func type
func* addr1 = &plainFunction; // OK
func* addr2 = &templateFunction<int>; // OK
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With