8
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修飾子の問題です。これはコンパイラのバグですか?

4

3 に答える 3

10

いいえ、これは仕様です。呼び出し規約は関数宣言の大部分であり、テンプレート関数はデフォルトの呼び出し規約を使用します。/Gz でコンパイルしない限り、これは __stdcall ではありません。デフォルトは /Gd、__cdecl です。

x64 には呼び出し規約が 1 つしかないため、x64 をターゲットにするとコードがコンパイルされます。

修理:

template<class R, class T0, class T1>
class TFunction<R (__stdcall *)(T0,T1)>
{
    // etc..
};
于 2011-05-13T12:16:35.083 に答える
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);
};

もちろん、これは無視されないR(__stdcall *)(T0, T1)Win32では一致しません。__stdcall関数ポインターに部分的に特化したい場合は、受け入れたい呼び出し規約ごとに部分的な仕様が必要になります。

于 2011-05-13T12:16:11.437 に答える
1

stdcall ケース用にテンプレートを特化していません。つまり、

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

構文については不明で、テストされていませんが、それが問題になるはずです。

于 2011-05-13T12:16:57.890 に答える