2015-12-15 6 views
5

मान लीजिए मैं std::conditional उपयोग करने के लिए, एक प्रकार का निर्धारण करना चाहते हैं का निर्माण संभव है, तो प्रकार एक vector<...> वापसी एक vector<...>::size_type हो जाएगा और यदि नहीं यह int हो जाएगा। (बस एक उदाहरण)।यह एक lazy_conditional metafunction

एक अनुभवहीन std::conditional उपयोग करने के लिए जिस तरह से:

template<class V> struct is_vector : std::false_type{}; 
template<class T> struct is_vector<std::vector<T>> : std::true_type{}; 

template<class C> 
using my_size_type = typename std::conditional< 
    not is_vector<C>::value, 
    int, 
    C::size_type // note that this line only makes sense when condition is false 
>::type; 

हालांकि यह विफल हो जाता है क्योंकि अगर C कहना है एक double, double::size_type एक त्रुटि दे देंगे, कि भले ही दूसरे झूठे विकल्प के मूल्यांकन है।

तो, मुझे आश्चर्य है कि lazy_conditional का एक प्रकार है जिसमें झूठा (या दूसरा झूठा) कथन का मूल्यांकन नहीं किया जाता है।

मुझे यहां कुछ मिला: https://stackoverflow.com/a/5317659/225186 लेकिन मुझे नहीं पता कि यह मेरे उदाहरण का उपयोग कैसे करें।


नोट मुझे पता है कि कैसे std::conditional का उपयोग किए बिना एक ही परिणाम प्राप्त करने के लिए:

template<class V> struct my_size_type{typedef int type;}; 
template<class T> struct my_size_type<std::vector<T>>{typedef std::vector<T>::size_type type;}; 

सवाल है, अगर वहाँ एक lazy_conditional है कि किसी तरह एक std::conditional कि लघु सर्किट है समझाया है।


कुछ परीक्षण त्रुटि मैं https://stackoverflow.com/a/5317659/225186 में विचारों का उपयोग करें और यह है कि इस प्रकार के लिए प्राप्त करने का प्रबंधन करने के बाद। यह मुझे यह भी सोचता है कि std::lazy_conditional लिखना संभव नहीं है क्योंकि C::size_type किसी भी अभिव्यक्ति में किसी भी अभिव्यक्ति में प्रकट नहीं हो सकता है, इसलिए दो-चरणीय अभिव्यक्तियों की आवश्यकता है।

template<class C, bool B> struct false_case{ 
    typedef void type; 
}; 
template<class C> struct false_case<C, false>{ 
    typedef typename C::size_type type; 
}; 

template<class C> 
using size_type = typename std::conditional< 
    not is_vector<C>::value, 
    int, 
    typename false_case<C, not is_vector<C>::value>::type 
>::type; 

मैं इसे मैक्रो में भी सघन नहीं कर सका, क्योंकि प्रत्येक मामला अलग है।

उत्तर

4

आपको संकेत के स्तर की आवश्यकता है।

template<class T> struct identity { using type = T; }; 

template<class C> 
struct size_type_of : identity<typename C::size_type> { }; 

template<class C> 
using size_type = typename std::conditional<not is_vector<C>::value, 
              identity<int>, 
              size_type_of<C>>::type::type; 

बिंदु (size_type_of<C> instantiating द्वारा) C::size_type को देख देरी करने के लिए जब तक आप जानते हैं कि यह एक है।


यदि आप वास्तव में क्या करना चाहते हैं कि "C::size_type यदि वह मौजूद है, int अन्यथा", तो std::experimental::detected_or_t अपने दोस्त है:

template<class C> 
using size_type_t = typename C::size_type; 

template<class C> 
using size_type_or_default = std::experimental::detected_or_t<int, size_type_t, C>; 
+0

ठीक है, और मुझे लगता है कि यह एक के रूप में समझाया नहीं जा सकता 'lazy_conditional <सी, टी, lazy_F>'। वैसे भी यह भी दिखाता है कि जब संभव हो तो मुफ्त मेटाफंक्शन सदस्य से बेहतर होता है (std :: size_type_of :: टाइप करें :: T :: size_type पर भरोसा करने के बजाय टाइप करें) (जैसे सामान्य फ़ंक्शन जेनेरिक कोड के लिए सदस्य फ़ंक्शंस से बेहतर है)। – alfC

+0

आह, यह कुछ ऐसा है जो मैं बार-बार खोजता हूं, अंत में यह वही है जैसा मैंने यहां किया था: http://stackoverflow.com/questions/5839357/detect-operator-support-with-decltype-sfinae/18603716# 18603716 – alfC

+0

'detect_or_t' संगतता पर: http://stackoverflow.com/questions/36418570/what-compiler-option-library-do-i-need-to-use-detect-or-t-type-trait?noredirect= 1 # comment60486585_36418570 – alfC

संबंधित मुद्दे