2012-10-17 33 views
8

विभिन्न compilers पर निम्न कोड को संकलित करने की कोशिश कर रहा मुझे दो अलग-अलग परिणाम देता है:क्या किसी वर्ग के सदस्य को अपना नाम (अन्य वर्ग) के समान नाम दिया जा सकता है?

struct S{}; 
struct T{S S;}; 
int main(){} 

आप देख सकते हैं, T अंदर, मैं एक वस्तु पहले से परिभाषित वर्ग S रूप में एक ही नाम पर रखा गया है।


जीसीसी 4.7.2 पर, I get the following errorT अंदर S S; घोषणा से संबंधित:

error: declaration of 'S T::S' [-fpermissive]
error: changes meaning of 'S' from 'struct S' [-fpermissive]

हालांकि, वर्ग के बाहर ले जाकर (या main में) works fine:

struct S{}; 
S S; 
int main(){} 

यह मुझे क्या त्रुटि दे रहा है इसका मतलब क्या है?


विजुअल स्टूडियो 2012 में, पूरी चीज किसी भी त्रुटि के बिना संकलित और चलाती है। इसे this Clang 3.0 compiler में पेस्ट करने से मुझे कोई त्रुटि नहीं मिलती है।

कौन सा सही है? क्या मैं वास्तव में ऐसा कर सकता हूं या नहीं?

+0

आह, मैं देखता हूं - मैं निदान को गलत तरीके से पढ़ता हूं। – ildjarn

+1

@ildjarn, यह एक अजीब झंडा है। ऐसा लगता है कि रिवर्स में काम करता है। आम तौर पर, चेतावनी के लिए ज़िम्मेदार ध्वज स्क्वायर ब्रैकेट में दिखाई देता है। – chris

+2

बस मत करो। क्या बात है? भ्रमित? ध्यान दें कि ऐसा करने के बाद, अब आप नामस्थानों में स्पष्ट रूप से योग्यता के बिना सदस्य कार्यों में 'S' प्रकार का उल्लेख नहीं कर सकते हैं ... –

उत्तर

14

जीसीसी

A name N used in a class S shall refer to the same declaration in its context and when re-evaluated in the completed scope of S. No diagnostic is required for a violation of this rule.

हालांकि, ध्यान दें कि no diagnostic is required, इसलिए सभी compilers अनुरूप रहे हैं सही है, [3.3.7 कक्षा स्कोप] से।

कारण क्लास स्कोप कैसे काम करता है इसका कारण है। जब आप S S;Sसंपूर्ण कक्षा में दिखाई देते हैं और S का उपयोग करते समय इसका अर्थ बदलते हैं।

struct S{}; 
struct T{ 
    void foo() 
    { 
     S myS; // Not possible anymore because S refers to local S 
    } 
    S S; 
}; 
+1

तर्क, आईआईआरसी, कक्षा के भीतर वर्ग सदस्य कार्यों की परिभाषा की अनुमति देना है। यदि नाम का अर्थ कक्षा में बदल जाता है तो उनके अंदर नाम लुकअप फंकी होगी। (यह पहले से ही काफी कठिन है)। – MSalters

+0

वही उदाहरण सी # में सही अर्थशास्त्र के साथ पूरी तरह से काम करता है। 'एसम्बर भी सही अर्थशास्त्र के साथ प्रयोग योग्य है। सी # उस संदर्भ को अलग करने में सक्षम है जहां 'एस' का उपयोग किया जाता है और यह स्पष्ट नहीं है कि सी ++ कंपाइलर्स ऐसा करने में सक्षम क्यों नहीं होना चाहिए। – ceztko

6

यह कोड खराब है, कोई निदान आवश्यक नहीं है। डायग्नोस्टिक की तरह, अगर घोषणा एक नाम का उपयोग करती है और नाम की तुलना में अलग अर्थ होता है, तो कक्षा परिभाषा के अंत में देखा जाता है, प्रोग्राम खराब है, कोई निदान आवश्यक नहीं है।

+0

एक और दिन जहां मैं खुद को बेहतर बना रहा हूं! +1 –

6

@JesseGood पूरा जवाब प्रदान करते हैं, लेकिन अगर आप वास्तव में किसी भी त्रुटि के बिना ऐसा करना चाहते हैं, तो आप प्रकार का पूरा नाम उपयोग कर सकते हैं और यह इस प्रकार काम करेगा:

struct S {}; 
struct T { ::S S; }; 
int main() {return 0;} 

नहीं कोई त्रुटि, क्योंकि आपकी कक्षा में ST::S है और इसका प्रकार ::S है!