问题
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?
回答1:
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..
};
回答2:
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.
回答3:
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.
来源:https://stackoverflow.com/questions/5991507/template-partial-specialization-for-stdcall-function-pointer