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>
,对于第二行它将是static_all_of<true, false, true>