下記のように、パラメータパックで入ってきたクラス全部が特定のクラスの子であることをチェックしたい。探したが見つからなかったので自分で作る。
// OK template<class Base,class Class> class MyClass { static_assert(std::is_base_of<Base, Class>::value, " Class is invalid"); }; // NG template<class Base, class... Classes> class MyClass2 { static_assert(std::is_base_of<Base, Classes...>::value, " Class are invalid"); };
まず、以下のようにテスト用のクラスを定義しておく。
class MyBase { int a; }; class MyDeri1 :public MyBase{ int b; }; class MyDeri2 :public MyBase { int c; }; class Independent{ int d; };
次に、そもそもstd::is_base_ofのvalueが型としては何なのかを知りたいので、以下のようにチェックする。
std::cout << std::is_base_of< std::true_type, std::is_base_of<MyBase, MyDeri1>>::value;
出力:
と、std::is_base_ofは最終的にはstd::true_typeかstd::false_typeになることが分かったので、それと同じようになるようにare_derived_fromも実装する。are_derived_fromが英語的にどうかは知らい。
template<class Base, class CHead, class ...Classes> struct are_derived_from : public std::conditional< std::is_base_of<Base, CHead>::value, //CHeadに対して評価 are_derived_from<Base, Classes...>, // 上評価がtrueならそれ以外の型についても調べる std::false_type // 一つでもfalseなら全部falseになる >::type { }; //末尾の特殊化 template<class Base, class CTail> struct are_derived_from<Base, CTail> : public std::is_base_of<Base, CTail> { };
int main() { std::cout << are_derived_from<MyBase, MyDeri1, MyDeri2>::value << std::endl; std::cout << are_derived_from<MyBase, MyDeri1, Independent>::value << std::endl; }
出力:
1
0