2013-11-28 20 views
5

++のようなプログラム何か:C++クラスの継承とテンプレート

class A { 
public: 
    void a(); 
} 

template <class B extends A> 
class C { 
B instance; 
} 

が可能、このですか?言い換えれば、C++はテンプレート内のクラスが他のもののサブクラスだと言うことができますか?

+0

@ LuchianGrigore:類似していますが、それは関数に関するもので、これはクラスに関するものです。ソリューションはわずかに異なる場合があります(たとえば、enable_ifがそこでの最上位の回答ですが、ここではあまり意味がありません)。 –

答えて

4

実際に直接的な方法ではありません。しかし、あなたはこのように、type_traitsstatic_assertを使用することができます。

static_assert(is_base_of<A,B>::value, "C<B> requires B:A"); 

あなたは、たとえば、あなたのコンストラクタでそれを置くことができ、それは要件が満たされない場合、コンパイルに失敗します。これはC++ 11のすべてのものですが、それ以前にはBoostに存在しています。また、実際にスタックされている場合(言語サポートは必要ありません)、自分でコードを作成できます。あなたの代わりにこれを書くことができ、

template <class B> 
class C 
{ 
    //here you can check it, and generate your own error message! 
    static_assert(extends<B,A>(), 
       "Constraint Violation: B doesn't derive from A."); 

    B instance; 
}; 

または:次にとしてあなたのクラスを定義

template<typename D, typename B> 
using extends = std::is_base_of<B,D>; 

5

として(ちょうど砂糖でコーティングされた名前である)extendsと呼ばれるメタ関数を定義:

//define it a bit differently now! 
template<typename D, typename B> 
using extends = typename std::enable_if<std::is_base_of<B,D>::value>::type; 

template <class B, class Unused=extends<B,A>> 
class C 
{ 
     B instance; 
}; 

しかし、この場合、独自のエラーを生成する機会はありませんrメッセージ。コンパイラは、のエラーメッセージを自由にスローすることができますが、これは理解しにくい場合があります。

とにかく、std::is_base_of<>を直接使用することができます。しかし、砂糖を塗ったの名前がの場合は、extendsが良いと思う!

+0

2番目の例で 'Unused'を削除できます –