typedef bool (*my_function_f)(int, double);
typedef bool (__stdcall *my_function_f2)(int, double);
// ^^^^^^^^^
template<class F> class TFunction;
template<class R, class T0, class T1>
class TFunction<R(*)(T0,T1)>
{
typedef R (*func_type)(T0,T1);
};
int main()
{
TFunction<my_function_f> t1; // works on x64 and win32
TFunction<my_function_f2> t2; // works on x64 and doesn't work on win32
return 0;
}
The code above gives me the following error in Visual C++ 2010:
1>e:\project\orwell\head\multimapwizard\trunk\externals.cpp(49): error C2079: 't2' uses undefined class 'Externals::TFunction<F>'
1> with
1> [
1> F=Externals::my_function_f2
1> ]
As you can see the problem with __stdcall
modifier. Is this the compiler bug?
No, this is by design. The calling convention is very much part of the function declaration, your template function uses the default calling convention. Which is not __stdcall unless you compile with /Gz. The default is /Gd, __cdecl.
The code compiles when you target x64 because it blissfully has only one calling convention.
Fix:
template<class R, class T0, class T1>
class TFunction<R (__stdcall *)(T0,T1)>
{
// etc..
};
This is because (*) means default calling convention, which is __cdecl
.
template<class R, class T0, class T1>
class TFunction<R(*)(T0,T1)>
{
typedef R (*func_type)(T0,T1);
};
is actually equal to
template<class R, class T0, class T1>
class TFunction<R(__cdecl *)(T0,T1)>
{
typedef R (__cdecl *func_type)(T0,T1);
};
which, of course, will not match an R(__stdcall *)(T0, T1)
on Win32 where __stdcall
is not ignored. If you want to partially specialize for function pointers then you will need a partial spec for every calling convention you want to accept.
You have not specialized your template for the stdcall case, i.e. you need
template<class R, class T0, class T1>
class TFunction<R(__stdcall *)(T0,T1)>
{
typedef R (*func_type)(T0,T1);
};
Not sure about the syntax, untested, but that should be the issue.
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