0

そのように宣言されたクラステンプレートを特殊化しようとしています:

template<typename T> class A;

関数ポインターを返す関数の場合。これは、関数の任意のアリティに対する汎用シグネチャである必要があります。

したがって、C/C++ 構文がどのように機能するかを知っていると仮定すると、型を返す関数の特殊化は次のようになりますResultType

template<typename ResultType, typename Arg1, typename Arg2>
A<ResultType(Arg1, Arg2)> {...};

そして、それを拡張して ResultType を関数ポインターにすることは、次のようになります。

template<typename FpResultType, typename FpArg1, typename Arg1, typename Arg2>
A<(ResultType(*)(FpArg1))(Arg1, Arg2)> {...};

ただし、これにより、GCC 4.6 では「無効なテンプレート パラメータ」が発生します。

私の知る限り、typedef はここでは使用できません。ユーティリティ クラスを追加して typedef を作成することは、テンプレート宣言の型名のリストから別のテンプレート型内に型を移動し、A のテンプレートの特殊化からそれらを「隠す」ため (結果として、コンパイル-宣言された型名が特殊化で使用されていないというエラー)。

enable_ifs と utility 構造体の長く複雑なチェーンを持つことは避けたいと思います。しかし、それが唯一の方法である場合は、まぁ。

4

1 に答える 1

2

次のように特化すると、これが機能すると思います。

template<typename FpResultType, typename FpArg1, typename Arg1, typename Arg2>
A<ResultType (*(Arg1, Arg2))(FpArg1)> {...};

次のコードでテストしたところ、正常にコンパイルされました (Clang を使用)。

template<typename T> class A;

template<typename FnRetT, typename FnArgT, typename Arg1, typename Arg2>
class A<FnRetT (*(Arg1, Arg2))(FnArgT)>
{
public:
  typedef FnRetT fn_ret_t;
};

float foo(float a)
{
  return a;
}

float (*getfn(int arg1, int arg2))(float)
{
  return foo;
}

int main(int argc, const char * argv[])
{
  typedef A<decltype(getfn)>::fn_ret_t ret_ty;

  return 0;
}

関数型を一致させるために使用される構文は、 の宣言と一致することに注意してくださいgetfn

于 2013-06-26T05:46:30.043 に答える