2011-07-01 15 views
10

this question पढ़ने के दौरान, मैं @Johannes के उत्तर में आया।तर्क के लिए अलग-अलग टेम्पलेट सिंटैक्स एक वर्ग है या नहीं

template<typename> struct void_ { typedef void type; }; 

template<typename T, typename = void> // Line 1 
struct is_class { static bool const value = false; }; 

template<typename T> 
struct is_class<T, typename void_<int T::*>::type> { // Line 2 
    static bool const value = true; 
}; 

यह निर्माण पाता है कि given type is a class or not है। इस छोटे मेटा कार्यक्रम को लिखने के लिए मुझे किस तरह का वाक्यविन्यास है। क्या कोई विस्तार से समझा सकता है:

  1. हमें लाइन 1 की आवश्यकता क्यों है?
  2. लाइन 2 में <int T::*>template पैरामीटर के रूप में वाक्यविन्यास का अर्थ क्या है?

उत्तर

10

रेखा 1: परीक्षण सफल होने पर नीचे आंशिक विशेषज्ञता का चयन करना।

रेखा 2: int T::* केवल तभी मान्य है जब T एक वर्ग प्रकार है, क्योंकि यह सदस्य सूचक को इंगित करता है।

जैसे, अगर यह वैध है, void_<T>::typevoid पैदावार, इस आंशिक विशेषज्ञता true के value साथ इन्स्टेन्शियशन के लिए चुना है। यदि T कक्षा प्रकार का नहीं है, तो यह आंशिक विशेषज्ञता चित्र से बाहर है SFINAE के लिए धन्यवाद और यह false के साथ सामान्य टेम्पलेट पर वापस आ गया है।

हर बार जब आप T::SOMETHING देखते हैं, तो SOMETHING मौजूद नहीं है, तो यह एक प्रकार, डेटा सदस्य या एक साधारण सूचक परिभाषा है, आपको SFINAE जा रहा है।

+2

क्यों है 'struct is_class <टी, टाइपनाम void_ :: प्रकार>' (सरल 'संरचना is_class 'के बजाय) की आवश्यकता है? (दूसरा संकलन लेकिन वांछित परिणाम नहीं देता है) – AProgrammer

+0

@AProgrammer: यदि आप कक्षा के प्रकार को नहीं जानते हैं तो दूसरा संकलन कैसे होता है?आप डिफ़ॉल्ट कैसे चुनेंगे, जो इस मामले में 'typename = void' है? – Xeo

+2

'is_class' (यानी 'typename = void') के पहले संस्करण में' void _ :: type' और डिफ़ॉल्ट पैरामीटर क्यों होना चाहिए? – iammilind

1

1. लाइन 1 पूर्णांक, लंबे और इतने पर की तरह है, जो एक वर्ग नहीं है कुछ के लिए प्रयोग किया जाता है ...

उदाहरण के लिए

:

class foo {}; 

if (is_class<foo>::value) // is a class 
    line_2 called 
else // if not 
    line 1 called 

एक आंशिक विशेषज्ञता इतना है की वजह से वहाँ लाइन 1 वह है जो आपके पास है, अन्यथा आपको एक त्रुटि मिलेगी जो कि कोई वर्ग नहीं है (जैसे char *, long, int ...)

2: int टी की कुंजी: : * ":: *" है, यह सी ++

में एक मानक ऑपरेटर है

का अर्थ है किसी वर्ग के सदस्य को पॉइंटर पॉइंट, एक फ़ंक्शन या डेटा फ़ील्ड, दोनों हो सकता है और इस मामले में इसका मतलब है कि कोई सदस्य है या सदस्य पॉइंटर के साथ काम कर सकता है, यह केवल कक्षाओं के लिए काम करता है , structs, या यूनियन सी ++ में, तो इसका परिणाम, आपको पता चलेगा कि पैरामीटर एक वर्ग है या नहीं।

btw, जैसे कुछ कीवर्ड गूगल: C++ टेम्पलेट, आंशिक विशेषज्ञता, और प्रकार लक्षण, या बढ़ावा प्रकार लक्षण

आशा है कि यह आप के लिए उपयोगी है :)

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