2010-01-24 17 views
10

मुझे पता चला कि operator<< किसी प्रकार के लिए प्रदान किया गया है या नहीं।SFINAE + sizeof = पता लगाएं कि अभिव्यक्ति संकलित

template<class T> T& lvalue_of_type(); 
template<class T> T rvalue_of_type(); 

template<class T> 
struct is_printable 
{ 
    template<class U> static char test(char(*)[sizeof(
     lvalue_of_type<std::ostream>() << rvalue_of_type<U>() 
    )]); 
    template<class U> static long test(...); 

    enum { value = 1 == sizeof test<T>(0) }; 
    typedef boost::integral_constant<bool, value> type; 
}; 

क्या यह चाल अच्छी तरह से जानी जाती है, या मैंने मेटाप्रोग्रामिंग नोबेल पुरस्कार जीता है? ;)

संपादित करें: मैंने कोड को दो वैश्विक फ़ंक्शन टेम्पलेट घोषणाओं lvalue_of_type और rvalue_of_type के साथ अनुकूलित करने के लिए आसान और आसान बनाने के लिए बनाया है।

+0

++ ऐसा लगता है कि 'is_printable :: मान' किसी भी एक्स के लिए सच है, और Comeau साथ ऑनलाइन यह किसी भी एक्स – UncleBens

+0

जी के साथ के लिए झूठी प्रतीत होता है ++, मैं' is_printable :: मान' और के लिए 1 मिलता है 'Is_printable > :: value' के लिए 0, इसलिए यह मेरे लिए ठीक काम करता है। – fredoverflow

+4

तो यह 3 कंपेलरों में से 1 पर काम करता है ... – UncleBens

उत्तर

5

यह एक अच्छी तरह से ज्ञात तकनीक, मैं :-)

sizeof ऑपरेटर में एक समारोह कॉल के उपयोग के डर लग रहा है है संकलक का निर्देश तर्क कटौती और समारोह मिलान प्रदर्शन करने के लिए, निश्चित रूप से संकलन समय पर। साथ ही, टेम्पलेट फ़ंक्शन के साथ, कंपाइलर टेम्पलेट से कंक्रीट फ़ंक्शन को भी तुरंत चालू करता है। हालांकि, यह अभिव्यक्ति फ़ंक्शन कॉल उत्पन्न नहीं करती है। यह अच्छी तरह से SFINAE Sono Buoni पीडीएफ में वर्णित है।

अन्य C++ SFINAE examples देखें।

कुलपति के साथ
1

यह सिर्फ दो प्रसिद्ध चालों का संयोजन है। SFINAE का कहना है कि 'प्रतिस्थापन विफलता एक त्रुटि नहीं है' - यह वही है जो आपने किया था। sizeof का उपयोग करके कंपाइलर विकल्प टेम्पलेट तर्क को वास्तव में निष्पादित किए बिना अभिव्यक्ति में जाने दें ताकि यह भी आम हो।

क्षमा करें :-)

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