2012-11-26 7 views
8

テンプレート引数として指定された型が、パラメータパックieにリストされているすべての型を実装しているかどうか、静的なアサーションを持つ可能性はありますか?パラメータパック対応のstd :: is_base_of()?パラメータパックに対応する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); 
    } 
}; 
+0

を。また、最初の 'is_base_of :: value'には第2引数の記述がありません。 – iammilind

+0

'static_assertion'はコンパイル時のプロセスです([こちら](http://stackoverflow.com/questions/1647895/what-does-static-assert-do-and-what-would-you-use-it-for))コンパイル時にコンパイラが 'is_base_of'値をチェックしますか? –

+1

@tAmirNaghizadehもちろん、 'is_base_of'はテンプレート自体であり、テンプレートはコンパイル時にインスタンス化されます。 –

答えて

14

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; 
} 

パックの拡張は、あなたがstd::is_base_of<Type, ?>::valueに疑問符ためRequirements...内のすべての種類を挿入することにより取得する値のリストに展開されますつまり、メインの最初の行のためにそれはstatic_all_of<true, true>に拡大し、二行目のためには、static_all_of<true, false, true>

+1

有望そうです。ありがとう! –

3
になりますただ、今後の参考のため

、私はC++ 17あなたは今、このような折り畳み式を使用することができますし、この問題を持っていたので:それが可能だ場合、私は疑問

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>()); 
関連する問題