2012-12-19 28 views
6

मुझे वैरिएड टेम्पलेट कक्षाओं के साथ SFINAE का उपयोग करने के लिए एक अच्छा समाधान नहीं मिल रहा है।विविधता टेम्पलेट कक्षाओं के साथ SFINAE?

template<typename... Args> 
class NoRef 
{ 
    //if any of Args... is a reference, this class will break 
    //for example: 
    std::tuple<std::unique_ptr<Args>...> uptrs; 
}; 

और एक वर्ग जो आसानी से जाँच करता है, तो एक तर्क पैक संदर्भ शामिल हैं:

template<typename T, typename... Other> 
struct RefCheck 
{ 
    static const bool value = std::is_reference<T>::value || RefCheck<Other...>::value; 
}; 
template<typename T> 
struct RefCheck<T> 
{ 
    static const bool value = std::is_reference<T>::value; 
}; 

मैं कैसे उपयोग करते हैं

चलो कहते हैं कि मैं एक variadic टेम्पलेट वस्तु जो संदर्भ पसंद नहीं करता है चलो यह उस मामले के लिए नोआरफ का विशेषज्ञ है जहां तर्क पैक में संदर्भ मौजूद हैं?

उत्तर

9

यह SFINAE का उपयोग नहीं करता है, लेकिन अनिवार्य रूप से करता है कि आप क्या करना चाहते हैं:

template<bool Ref, typename... Args> 
class NoRef_; 

template<typename... Args> 
class NoRef_<false, Args...> 
{ 
    std::tuple<std::unique_ptr<Args>...> uptrs; 
}; 
template<typename... Args> 
class NoRef_<true, Args...> 
{ 
    // contains reference 
}; 

template<typename... Args> 
using NoRef = NoRef_<RefCheck<Args...>::value, Args...>; 

// alternative from Nawaz 

template<typename... Args> struct NoRef : NoRef_<RefCheck<Args...>::value, Args...> {} 
+0

+1। लेकिन मुझे लगता है कि 'टेम्पलेट <टाइपनाम ... Args> struct NoRef: NoRef_ :: मान, Args ...> {}; 'बेहतर होगा। अब 'नोआरफ' गैर-प्रकार टेम्पलेट पैरामीटर (यानी बूलियन मान) के बिना एक अलग वर्ग टेम्पलेट है। – Nawaz

+0

मुझे यह समाधान पसंद है, भले ही मैं अभी भी एमएसवीसी में टेम्पलेट्स को उपनाम नहीं कर सकता। लेकिन नवाज ने भी इसका समाधान प्रदान किया। –

6

मुझे डर है कि यह संभव नहीं है, क्योंकि टेम्पलेट पैक अनावश्यक हैं। हालांकि, आप पैक पैक कर सकते हैं।

// Used to transport a full pack in a single template argument 
template <typename... Args> struct Pack {}; 

हम संदर्भ जाँच अनुकूलन:

template <typename T, typename... Other> 
struct RefCheck 
{ 
    static const bool value = std::is_reference<T>::value 
          || RefCheck<Other...>::value; 
}; 

template <typename T> 
struct RefCheck<T> 
{ 
    static const bool value = std::is_reference<T>::value; 
}; 

template <typename... Args> 
struct RefCheck<Pack<Args...>>: RefCheck<Args...> {}; 

और अब हम उपयोग कर सकते हैं Pack:

template <typename P, bool = RefCheck<P>::value> class NoRef; 

template <typename... Args> 
class NoRef<Pack<Args...>, false> { 
    // no reference in Args... here 
};