2

いくつかの複雑な理由で、サポートされているタイプT(テンプレートから取得)を選択したタイプのリストに変換したいと思います。このために、「変換」という名前のテンプレート構造を使用してみました。例えば:

Convert<short>::type should be int
Convert<int>::type should be int
Convert<char>::type should be int
Convert<float>::type should be double
Convert<double>::type should be double
Convert<const char*>::type should be std::string
Convert<std::string>::type should be std::string
etc.

上記のものは、テンプレートの特殊化を使用して簡単に実装できます。しかし、問題を引き起こしている1つのケースがあります:

Convert<T>::type where T is a functor should be T

これを処理するには、SFINAEを使用する必要があると思いますが、コンパイルすることができません。

以下のコードは、「部分的な特殊化はプライマリテンプレートの引数リストと一致できません」(つまり、「変換」の記述は禁止されています)を示しています。

template<typename T, typename = decltype(&T::operator())>
struct Convert<T>       { typedef T type; };

そして、これは私に「テンプレートパラメータが使用されていないか、部分的な特殊化で推論可能」(つまり、Tが使用されていないと考えている)を与えます:

template<typename T>
struct Convert<typename std::enable_if<std::is_function<typename T::operator()>::value,T>::type>
 { typedef T type; };

どうすればよいかわかりません。すべての試行で、上記の2つのエラーのいずれかが発生します。

編集:同じモデルを使用して他の一般的なものをキャッチしたいので、特殊化されていない構造で「typedefTtype」とだけ書くことはできません。

ありがとう

4

1 に答える 1

2

最初のアプローチを使用することをお勧めしますが、それを機能させるには、

未使用のテンプレート引数を 1 つ使用してマスター テンプレートを宣言します。

template <class T, class = void> Convert;

void現在使用しているテンプレートのすべての特殊化にパラメーターを追加します。

次のように「ファンクターの専門化」を定義します。

template<typename T, typename std::enable_if<std::is_function<typename T::operator()>::value,void>::type>

つまり、2 番目の引数voidがファンクターである場合 (つまり、既定のテンプレート引数と一致する)、そうでない場合は存在しないことを意味します。

ところで、なぜ in を使用typenameするのtypename T::operator()ですか? 私の知る限り、operator()タイプではありません。

于 2010-07-24T10:37:40.683 に答える