を使用しています、私はそれが簡単になるだろうと一瞬思いました。そこで私はここで完全な解決策を提供しようとします。
形質
:一般的なアプローチは、問題のこのタイプは
特徴ヘルパーテンプレートを作成し、クラスの特殊化を決定する(C++ 11、ブーストまたは手動の実装のいずれか)
enable_if
と一緒にそれを使用することで解決します
単純なアプローチ、必ずしもだろう最高の、しかし、書き込みが簡単:
template <typename T>
struct has_nested_Vec {
typedef char yes;
typedef char (&no)[2];
template <typename U>
static yes test(typename U::Vec* p);
template <typename U>
static no test(...);
static const bool value = sizeof(test<T>(0)) == sizeof(yes);
};
アプローチは、異なるサイズの型を返すこと、2つのテンプレート機能を提供し、簡単です。そのうちの1つはネストされたVec
タイプを取り、もう1つは省略記号を取ります。 Vec
がネストされているすべてのタイプでは、最初のオーバーロードがよりよく一致します(省略記号はどのタイプでも最悪一致です)。 Vec
SFINAEがネストされていないタイプの場合、そのオーバーロードは破棄され、残りの唯一のオプションは省略記号になります。だから我々はタイプがネストされたVec
タイプを持っているかどうか尋ねる特性を持っています。
あなたが任意のライブラリからこれを使用することができ、またはあなた自身をロールバックすることができます
、それは非常に簡単であれば有効にします。
template <bool state, typename T = void>
struct enable_if {};
template <typename T>
struct enable_if<true,T> {
typedef T type;
};
最初の引数がfalse
ある場合は、ベーステンプレートがあります条件がtrue
の場合、enable_if
にはSFINAEで使用できるネストされたtype
がネストされています。type
はネストされていません。
実装
は、今、私たちは、テンプレートとネストされたVec
でのみのタイプのSFINAEを使用する特殊化を提供する必要があります:私たちは型にFunctor
をインスタンス化するたびに
template<class T, class V = void>
struct Functor {
void operator()() const {
std::cerr << "general" << std::endl;
}
};
template<class T>
struct Functor<T, typename enable_if<has_nested_Vec<T>::value>::type > {
void operator()() const {
std::cerr << "special" << std::endl;
}
};
、コンパイラは、has_nested_Vec
をインスタンス化し、enable_if
に渡された真理値を取得する特殊化を使用しようとします。値がfalse
であるタイプの場合、enable_if
にネストされたtype
タイプがないため、SFINAEで特殊化が破棄され、基本テンプレートが使用されます。あなたが本当に全体の形が、ちょうどオペレータを専門とする必要はないと思われるあなたの特定のケースでは、
あなたの特定のケース
、あなたは、単一の一つに三つの要素を混在させることができます。a
template <typename T>
class Functor {
template <typename U>
void op_impl(typename U::Vec* p) const {
std::cout << "specialized";
}
template <typename U>
void op_impl(...) const {
std::cout << "general";
}
public:
void operator()() const {
op_impl<T>(0);
}
};
'compiler'タグを削除しました。これは一般に、コンパイルプロセス自体についての質問に使用されますが、この質問はC++言語に関するものです。 –