The pack parameter knows std :: is_base_of ()

Is it possible to get a static statement about whether the type provided as an argument to the template implements all the types listed in the parameter package, i.e. does the parameter package know std :: is_base_of ()?

template <typename Type, typename... Requirements> class CommonBase { static_assert(is_base_of<Requirements..., Type>::value, "Invalid."); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ parameter pack aware version of std::is_base_of() public: template <typename T> T* as() { static_assert(std::is_base_of<Requirements..., T>::value, "Invalid."); return reinterpret_cast<T*>(this); } }; 
+8
c ++ templates typetraits variadic-templates
source share
2 answers

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>

+15
source share

Just for future reference, because I had this problem, with C ++ 17 you can now use folding expressions as follows:

 template<typename Base, typename... Args> constexpr auto all_base_of() { return (std::is_base_of<Base, Args>::value && ...); } static_assert(all_base_of<Base, A, B, C>()); 
+3
source share

All Articles