2015-01-19 10 views
11

क्यों है कि मामला गलत (यह तार्किक)typedef और टेम्पलेट पैरामीटर

template <typename T> 
struct Der: public Base 
{ 
    typedef int T; 
    T val; 
}; 

है, लेकिन स्थिति सही है?

struct Base 
{ 
    typedef int T; 
}; 

template <typename T> 
struct Der: public Base 
{ 
    T val; 
}; 

स्टैंडर्ड 14.6.1/7 का कहना है:

एक वर्ग टेम्पलेट की परिभाषा में या इस तरह के एक टेम्पलेट के एक सदस्य टेम्पलेट परिभाषा के बाहर प्रतीत होता है कि की परिभाषा में, प्रत्येक के लिए आधार वर्ग है जो एक टेम्पलेट पैरामीटर (14.6.2) पर निर्भर नहीं करता, अगर आधार वर्ग या आधार वर्ग के एक सदस्य के नाम के नाम पर एक टेम्पलेट पैरामीटर का नाम, आधार वर्ग नाम के समान है या सदस्य नाम टेम्पलेट पैरामीटर नाम (3.3.7) छुपाता है।

यह यहां अस्पष्ट क्यों नहीं है?

उत्तर

15

पहला उदाहरण [temp.local]/6 के अनुसार गलत है:

एक टेम्पलेट पैरामीटर (नेस्टेड स्कोप सहित) अपने दायरे के भीतर redeclared नहीं किया जाएगा।

हालांकि,

template <typename T> 
struct Der: public Base 
{ 
    T val; 
}; 

T में नाम Base से विरासत में मिली द्वारा छिपा है - अपने उद्धरण द्वारा निर्दिष्ट के रूप में

[..] अगर आधार वर्ग या आधार वर्ग के एक सदस्य के नाम के नाम पर एक टेम्पलेट पैरामीटर के नाम के समान है, आधार वर्ग नाम या सदस्य नाम टेम्पलेट पैरामीटर नाम (3.3.7) छुपाता है।

यही है, सदस्य valint प्रकार का है। Demo

+0

आपके उत्तर के लिए धन्यवाद, लेकिन ऐसे व्यवहार के कारण क्या हैं? – user3514538

+1

@ user3514538 टेम्पलेट-पैरामीटर को फिर से शुरू करने से शायद [basic.scope.class]/1 - एक महत्वपूर्ण अनुच्छेद के साथ समस्याएं हो सकती हैं। ओडीआर का उल्लेख नहीं है। हालांकि, दूसरी बिट के बारे में, मुझे यकीन नहीं है। हमें एचवीडी के लिए इंतजार करना चाहिए: ओ) – Columbo

+1

यह [सीडब्ल्यूजी 591] (http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#591) का विषय प्रतीत होता है, हालांकि यह केवल इसे प्रतिबंधित करता है गैर-निर्भर आधार वर्गों पर शासन करें। – dyp

1

क्योंकि दूसरा unambigous है:

आप परवाह हो सकता है नहीं या पता है कि सुपर क्लास में typedev int T था कि, लेकिन आप केवल टेम्पलेट पैरामीटर, जो यह स्पष्ट है कि आप की बात कर रहे हैं बनाता है के रूप में पेश किया है T यह जब Der में T का उपयोग कर।

+3

व्युत्पन्न में 'टी' वास्तव में आधार के सदस्य है, 'बेस :: टी', दूसरे उदाहरण में। यह आपके उत्तर का विरोधाभास प्रतीत होता है - या क्या मुझे कुछ याद आ रही है? –

+0

मुझे नहीं लगता कि यह उत्तर _wrong_ प्रति से है, लेकिन यह वास्तव में कुछ भी नहीं समझाता है। –

+0

@ लाइटनेसरेसेसिन ऑर्बिट 'टी' बेस क्लास टाइपपीफ को संदर्भित करता है। उत्तर कहता है * "आपने अभी 'टी' को टेम्पलेट पैरामीटर के रूप में पेश किया है, जो यह स्पष्ट करता है कि आप डेर में' टी' का उपयोग करते समय इसका जिक्र कर रहे हैं। * * – Columbo

2

सामान्य में, मानक सुनिश्चित करने के लिए कि किसी दिए गए क्षेत्र में एक प्रकार का अर्थ एक ही है की कोशिश करता है।

यदि हम दिखाते हैं कि टाइपपीफ की अनुमति है तो val1, val2, और val3 के प्रकारों पर निम्नलिखित में विचार करें?

template <typename T> 
struct Der: public Base 
{ 
    void f1() { 
     T val1;  // What is the type of 'val1'? 
    } 

    T val2;  // What is the type of 'val2'? 

    typedef int T; 

    T val3;  // What is the type of 'val3'? 
}; 

केवल चर के लिए टेम्पलेट पैरामीटर प्रकार टी 'val2' होगा।

ऐसा इसलिए है क्योंकि मानक की आवश्यकता है कि कक्षा के सभी सदस्य f1 के लिए "दायरे में" हों। यही कारण है कि सदस्य कार्य कक्षा के बाद में परिभाषित सदस्य चर का उल्लेख कर सकते हैं। ,

typedef int T; 

struct S 
{ 
    T x; 
    typedef float T; 
    T y; 
}; 

फिर अगर यह तो Tx की घोषणा के लिए इस्तेमाल किया ::T को उल्लेख करता है और Ty के लिए इस्तेमाल किया उल्लेख करता है typedef करने के लिए कानूनी था:

एक ही समस्या भी typedefs साथ प्रदर्शन किया जा सकता S::T

यह आईएसओ 3.3.7/1 के तहत मानक द्वारा कवर किया जाता:

निम्नलिखित नियम नाम कक्षाओं में घोषित की गुंजाइश का वर्णन।

...

2) एक वर्ग एस में इस्तेमाल के संदर्भ में एक ही घोषणा का उल्लेख करेगा और एस के पूरा दायरे में जब फिर से मूल्यांकन नहीं निदान का उल्लंघन के लिए आवश्यक है एक नाम एन यह नियम।

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