2012-11-26 36 views
8

क्या स्थिर धारणा होने की संभावना है कि टेम्पलेट तर्क के रूप में प्रदान किया गया एक प्रकार पैरामीटर पैक यानी में सूचीबद्ध सभी प्रकारों को लागू करता है या नहीं। एक पैरामीटर पैक जागरूक 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' समय प्रक्रिया संकलित है ([यहां] (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

के लिए सी ++ 17 अद्यतन: सी ++ 17 के गुना भाव के साथ इस लगभग तुच्छ हो जाता है:

template <typename Type, typename... Requirements> 
class CommonBase 
{ 
    static_assert(std::is_base_of_v<Type, Requirements> && ..., "Invalid."); 
}; 

मूल उत्तर (सी ++ 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

बस भविष्य में संदर्भ के लिए है, क्योंकि मैं तो बस के साथ सी ++ 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>()); 
संबंधित मुद्दे