2012-11-26 44 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'也沒有提到第二個參數。 – iammilind

+0

'static_assertion'是編譯時過程([here](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; 
} 

該包的擴展將擴展到值,您在Requirements...將每一種類型爲std::is_base_of<Type, ?>::value問號,即在主要的一線得到的名單將擴大到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>()); 
相關問題