C++17 の更新:
C++17 の折り畳み式を使用すると、これはほとんど簡単になります。
template <typename Type, typename... Requirements>
class CommonBase
{
static_assert((std::is_base_of_v<Type, Requirements> && ...), "Invalid.");
};
元の回答 (C++11/14):
パック展開といくつかの静的バージョンを使用する場合がありますstd::all_of
:
template <bool... b> struct static_all_of;
//implementation: recurse, if the first argument is true
template <bool... tail>
struct static_all_of<true, tail...> : static_all_of<tail...> {};
//end recursion if first argument is false -
template <bool... tail>
struct static_all_of<false, tail...> : std::false_type {};
// - or if no more arguments
template <> struct static_all_of<> : std::true_type {};
template <typename Type, typename... Requirements>
class CommonBase
{
static_assert(static_all_of<std::is_base_of<Type, Requirements>::value...>::value, "Invalid.");
// pack expansion: ^^^
};
struct Base {};
struct Derived1 : Base {};
struct Derived2 : Base {};
struct NotDerived {};
int main()
{
CommonBase <Base, Derived1, Derived2> ok;
CommonBase <Base, Derived1, NotDerived, Derived2> error;
}
パック展開はRequirements...
、 の疑問符のすべてのタイプを挿入することによって得られる値のリストに展開されますstd::is_base_of<Type, ?>::value
。つまり、 main の最初の行は に展開さstatic_all_of<true, true>
れ、2 行目はstatic_all_of<true, false, true>