2011-04-21 16 views
6

私のケースでカスタム条件を使用してテンプレートのコードを生成することを制限する方法があるのでしょうか?テンプレートクラスTがクラスバーによってインヘリットされている場合のみfooを呼び出すようにしたい使用しているが)テンプレートクラス制限

template <class T:public bar> void foo() 
{ 
    // do something 
} 
+3

あなたはブースト 'enable_if'を使用することができるかもしれません。 –

+0

公開継承を扱っている場合は、さらにもう1つの方法があります。私の答えを見てください。 – iammilind

答えて

9

あなたは)(「置換の失敗はエラーではありません」SFINAEをTを制限することができます。

template <typename T> 
typename std::enable_if<std::is_base_of<bar, T>::value>::type foo() 
{ 

} 

T場合はbarに由来しない、関数テンプレートの特殊化を失敗します。過負荷解決時には考慮されません。 std::enable_ifstd::is_base_ofは、C++標準ライブラリの新しいコンポーネントで、今後のリビジョンC++ 0xに追加されています。コンパイラ/標準ライブラリの実装がまだそれらをサポートしていない場合は、C++ TR1またはBoost.TypeTraitsでそれらを見つけることもできます。

+0

実際、 'std'ライブラリに' is_base_of'がない場合、それはBoostにあります。 –

+0

はい。 Boostに相当するのは、 'boost :: enable_if > :: type'です。 'std :: enable_if'は最初の引数として' bool'をとりますが、 'boost :: enable_if'は型を取ります。 'std :: enable_if'は' boost :: enable_if_c'と同じです。 –

+0

あなたはstdライブラリ自体がどのようにクラスのenable_ifまたはis_base_ofに実装されているか考えていますか? – Ali1S232

0

はい、次の手法を使用できます(パブリック継承の場合)。 1つのポインタの初期化によるオーバーヘッドが発生します。

編集:再書き込み

template<typename Parent, typename Child> 
struct IsParentChild 
{ 
    static Parent* Check (Child *p) { return p; } 
    Parent* (*t_)(Child*); 
    IsParentChild() : t_(&Check) {} // function instantiation only 
}; 

template<typename T> 
void foo() 
{ 
    IsParentChild<Bar, T> check; 
// ... 
}