Update for C ++ 17: With C ++ 17 folded expressions, this becomes almost trivial:
template <typename Type, typename... Requirements> class CommonBase { static_assert((std::is_base_of_v<Type, Requirements> && ...), "Invalid."); };
Original answer (C ++ std::all_of ): You can use the package extension and some static version of 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; }
The package extension will expand to the list of values ββthat you get by inserting each type in Requirements... for the question mark in std::is_base_of<Type,?>::value , that is, for the first line in main, it will expand to static_all_of<true, true> , for the second line it will be static_all_of<true, false, true>
Arne mertz
source share