简体   繁体   English

__stdcall函数指针的模板部分特化

[英]Template partial specialization for __stdcall function pointer

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: 上面的代码在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. 正如您可以看到__stdcall修饰符的问题。 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. 除非用/ Gz编译,否则不是__stdcall。 The default is /Gd, __cdecl. 默认值为/ Gd,__ cdecl。

The code compiles when you target x64 because it blissfully has only one calling convention. 当您定位x64时,代码会编译,因为它幸福地只有一个调用约定。

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 . 这是因为(*)表示默认调用约定,即__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. 当然,它与Win32上的R(__stdcall *)(T0, T1)不匹配R(__stdcall *)(T0, T1)其中__stdcall不被忽略。 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, ie you need 您没有专门为stdcall案例设置模板,即您需要

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. 不确定语法,未经测试,但这应该是问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM