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;
}
上面的代码在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> ]
正如您可以看到__stdcall
修饰符的问题。这是编译器错误吗?
答案 0 :(得分:10)
不,这是设计的。调用约定是函数声明的一部分,您的模板函数使用默认的调用约定。除非用/ Gz编译,否则不是__stdcall。默认值为/ Gd,__ cdecl。
当您定位x64时代码会编译,因为它幸福地只有一个调用约定。
修正:
template<class R, class T0, class T1>
class TFunction<R (__stdcall *)(T0,T1)>
{
// etc..
};
答案 1 :(得分:4)
这是因为(*)表示默认调用约定,即__cdecl
。
template<class R, class T0, class T1>
class TFunction<R(*)(T0,T1)>
{
typedef R (*func_type)(T0,T1);
};
实际上等于
template<class R, class T0, class T1>
class TFunction<R(__cdecl *)(T0,T1)>
{
typedef R (__cdecl *func_type)(T0,T1);
};
当然,它与Win32上的R(__stdcall *)(T0, T1)
不匹配,其中__stdcall
未被忽略。如果你想部分专门用于函数指针,那么你需要为你想接受的每个调用约定提供一个部分规范。
答案 2 :(得分:1)
您还没有专门针对stdcall案例的模板,即您需要
template<class R, class T0, class T1>
class TFunction<R(__stdcall *)(T0,T1)>
{
typedef R (*func_type)(T0,T1);
};
不确定语法,未经测试,但这应该是问题。