++のようなプログラム何か:C++クラスの継承とテンプレート
class A {
public:
void a();
}
template <class B extends A>
class C {
B instance;
}
が可能、このですか?言い換えれば、C++はテンプレート内のクラスが他のもののサブクラスだと言うことができますか?
++のようなプログラム何か:C++クラスの継承とテンプレート
class A {
public:
void a();
}
template <class B extends A>
class C {
B instance;
}
が可能、このですか?言い換えれば、C++はテンプレート内のクラスが他のもののサブクラスだと言うことができますか?
実際に直接的な方法ではありません。しかし、あなたはこのように、type_traitsでstatic_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>;
:
として(ちょうど砂糖でコーティングされた名前である)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
が良いと思う!
2番目の例で 'Unused'を削除できます –
@ LuchianGrigore:類似していますが、それは関数に関するもので、これはクラスに関するものです。ソリューションはわずかに異なる場合があります(たとえば、enable_ifがそこでの最上位の回答ですが、ここではあまり意味がありません)。 –