2014-07-04 5 views
6

निम्नलिखित कोड gcc, vC++, और clang द्वारा स्वीकार किया जाता है।क्या यह सी ++ मानक-अनुपालन है जो 'ए <int> :: टेम्पलेट बी <int> x; `का उपयोग कर चर को परिभाषित करने के लिए है?

template<class T> 
struct A 
{ 
    template<class U> 
    struct B 
    {}; 
}; 

int main() 
{ 
    A<int>::B<int> y; // OK as expected 
    A<int>::template B<int> x; // Also OK! Is this standard-compliant? 
}; 

यह C++ एक चर A<int>::template B<int> x; का उपयोग कर परिभाषित करने के लिए मानक अनुरूप है?

+0

बी एक टेम्पलेट-निर्भर प्रकार टेम्पलेट है, इसलिए दूसरा वाक्यविन्यास बिल्कुल सही है। – Quentin

+0

क्या आप मुझे मानक के उस पृष्ठ पर संदर्भित कर सकते हैं जो इस उपयोग को निर्दिष्ट करता है? धन्यवाद। – xmllmx

+3

@peppe डुप्लिकेट नहीं है, क्योंकि आपको यहां 'टेम्पलेट' का उपयोग करने की आवश्यकता नहीं है। – juanchopanza

उत्तर

12

भले ही यह एक गैर-प्रामाणिक टिप्पणी है, मुझे लगता है कि एक जवाब से n3797 [temp.names]/6

दिया जा सकता है typename उपसर्ग के साथ मामला है, template उपसर्ग अनुमति दी है ऐसे मामलों में जहां यह सख्ती से जरूरी नहीं है; यानी, नेस्टेड-नाम-विनिर्देशक या -> या . के बाईं ओर की अभिव्यक्ति टेम्पलेट-पैरामीटर पर निर्भर नहीं है, या उपयोग टेम्पलेट के दायरे में प्रकट नहीं होता है।

ओपी के उदाहरण में, उपसर्ग template एक टेम्पलेट के दायरे से बाहर किया जाता है, और पूर्ववर्ती नेस्टेड-नाम-विनिर्देशक निर्भर नहीं है। इसलिए, उपसर्ग template आवश्यक नहीं है, लेकिन यहां अनुमति दी गई है।


[expr.prim.general]/8

योग्य-आईडी:
        नेस्टेड-नाम-विनिर्देशकtemplateऑप्ट   अयोग्य -आईडी

प्लस [temp.names]/5

एक नाम कीवर्ड template लगाया जाता है या एक टेम्पलेट आईडी होगा नाम एक वर्ग टेम्पलेट का उल्लेख होगा।

[temp.names]/1 का कहना है कि B<int> वास्तव में एक (सरल) टेम्पलेट आईडी है।

+0

यह सब सी ++ 11 + के लिए मान्य है, सी ++ 98/03 के लिए नहीं। क्या मैं सही हू? – Constructor

+2

@ Constructor C++ 03 में, आप कीवर्ड 'टेम्पलेट' का उपयोग कर सकते हैं भले ही * नेस्टेड-टाइप-नाम * निर्भर न हो; लेकिन आपको टेम्पलेट्स के दायरे से बाहर इसका उपयोग करने की अनुमति नहीं थी। – dyp

+0

हां, धन्यवाद। – Constructor

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