【问题标题】:Template partial specialization for __stdcall function pointer__stdcall 函数指针的模板部分特化
【发布时间】:2011-08-24 21:24:54
【问题描述】:
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 修饰符的问题。这是编译器的bug吗?

【问题讨论】:

标签: c++ templates template-specialization stdcall


【解决方案1】:

不,这是设计使然。调用约定是函数声明的很大一部分,您的模板函数使用默认调用约定。除非您使用 /Gz 编译,否则这不是 __stdcall。默认为 /Gd,__cdecl。

当您以 x64 为目标时,代码会编译,因为它只有一个调用约定。

修复:

template<class R, class T0, class T1>
class TFunction<R (__stdcall *)(T0,T1)>
{
    // etc..
};

【讨论】:

    【解决方案2】:

    您还没有为 stdcall 案例专门化您的模板,即您需要

    template<class R, class T0, class T1>
    class TFunction<R(__stdcall *)(T0,T1)>
    {
      typedef R (*func_type)(T0,T1);
    };
    

    不确定语法,未经测试,但这应该是问题。

    【讨论】:

      【解决方案3】:

      这是因为 (*) 表示默认调用约定,即__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 不会被忽略。如果您想部分专门化函数指针,那么您需要为您想要接受的每个调用约定提供部分规范。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-04
        • 1970-01-01
        • 2011-06-27
        • 1970-01-01
        • 2017-06-09
        • 2011-12-25
        相关资源
        最近更新 更多