क्या नाम रिक्त स्थान हैं और नियम क्या हैं?


9

नोट: इस सवाल के बारे में है name space, नहीं namespace

C ++ मानक के कुछ संदर्भ हैं name space, लेकिन मुझे इसकी परिभाषा दिखाई नहीं देती है। मानकों का कहना है कि लेबल और मैक्रो विभिन्न नाम रिक्त स्थान में हैं। अन्य सभी संदर्भ name spaceC / C ++ संगतता अनुभाग में हैं, जैसे कि ( वर्तमान ड्राफ्ट ):

यह C और C ++ के बीच की कुछ असंगतताओं में से एक है, जिसे नए C ++ नाम के स्थान की परिभाषा के लिए जिम्मेदार ठहराया जा सकता है, जहां एक नाम को एक प्रकार के रूप में और एक गैर-प्रकार में एक गैर-प्रकार के रूप में घोषित किया जा सकता है, जो गैर-प्रकार के नाम को छिपाने का कारण बनता है। प्रकार और नाम की आवश्यकता है कि कीवर्ड क्लास, स्ट्रक्चर, यूनियन या एनम का उपयोग टाइप नाम को संदर्भित करने के लिए किया जाए। यह नया नाम स्पेस डेफ़िनेशन C ++ प्रोग्रामर्स के लिए महत्वपूर्ण नोटिफ़िकेशंस प्रदान करता है और यूज़र-डिफ़ाइंड प्रकारों को मौलिक प्रकारों के उपयोग के लिए संभव बनाने में मदद करता है।

यह नया नाम अंतरिक्ष परिभाषा क्या है ? मैं इसे मानक में कहां पा सकता हूं? सटीक नियम क्या हैं? "गैर-प्रकार के छिपाने के प्रकार" की तुलना में नियम अधिक जटिल लगते हैं। जैसे, यह संकलन नहीं करता है:

typedef int Foo; // Foo is a type
void Foo();      // not a type, but compile error, instead of hiding

लेकिन यह करता है:

struct Foo { }; // Foo is a type as well
void Foo();     // This hides the type Foo. "struct Foo" refers to the type

और यह या तो संकलन नहीं है:

struct Foo { };   // Type
namespace Foo { } // Non-type, but compiler error instead of hiding

व्यावहारिक दृष्टिकोण यह है कि एक नामस्थान सभी-सार्वजनिक सदस्यों (उपवर्गों) के साथ एक एकल वर्ग है। कृपया मुझे लिंच न करें :-)
पेटेर - मोनिका

2
@ peterh-ReinstateMonica ने प्रश्न पढ़ा (फिर से)
YSC

एफडब्ल्यूआईडब्ल्यू, आपका लिंक संबंधित अनुभागों से लिंक करता है: प्रभावित उपवर्ग: [class.name] [यह भी देखें [dcl.typedef]] आप उन अनुभागों को देख सकते हैं कि नियम कैसे काम करते हैं।
नाथन ऑलवर

कम से कम दो नाम स्थान हैं: एक लेबल के लिए [stmt.label]/1और एक मैक्रोज़ के लिए [cpp]/8
वाईएससी

1
यह कुछ हद तक दिलचस्प है (मेरे लिए) कि वर्णन और उदाहरण दोनों के तर्क का उल्लेख करते हैं; एक प्रकार का नाम जो गैर-प्रकार का नाम छिपा रहा है। मसौदे की स्थिति को देखते हुए, मैं उम्मीद करूंगा कि परिवर्तन के लिए पैराग्राफ।
मोलबनिलो

जवाबों:


2

नाम अंतरिक्ष अवधि आईएसओ सी स्टैंडर्ड में और अधिक अच्छी तरह से स्थापित किया जा सकता है; आईएसओ C11 का हवाला देते हुए :

6.2.3 पहचानकर्ताओं के नाम स्थान

यदि किसी विशेष पहचानकर्ता की एक से अधिक घोषणा एक अनुवाद इकाई में किसी भी बिंदु पर दिखाई देती है, तो वाक्य-विन्यास संदर्भ अलग-अलग संस्थाओं को संदर्भित करता है। इस प्रकार, पहचानकर्ताओं की विभिन्न श्रेणियों के लिए अलग-अलग नाम स्थान हैं, निम्नानुसार हैं:

  • लेबल नाम (लेबल घोषणा और उपयोग के सिंटैक्स द्वारा अस्वीकृत);
  • कीवर्ड्स स्ट्रक्चर, यूनियन या एनम के ढांचे, यूनियनों और एनुमरेशंस (किसी भी 32 का अनुसरण करके अस्वीकृत) के टैग;
  • संरचनाओं या यूनियनों के सदस्य; प्रत्येक संरचना या संघ के पास अपने सदस्यों के लिए एक अलग नाम स्थान होता है (सदस्य या। -> ऑपरेटर के माध्यम से उपयोग करने के लिए उपयोग किए गए अभिव्यक्ति के प्रकार से असंबद्ध);
  • अन्य सभी पहचानकर्ता, जिन्हें साधारण पहचानकर्ता कहा जाता है (साधारण घोषणाकर्ताओं में या गणन स्थिरांक के रूप में घोषित)।

C ++ की नई नाम स्थान की परिभाषा , हालांकि, हाल के समय में किसी भी तरह से नहीं है , और इसका वर्तमान रूप में [diff.class] / 1 में वर्णन किया गया है क्योंकि 'C98 में ISO C ++ मानक की शुरूआत के बाद से । यह केवल संदर्भों में किसी भी लंबाई में उल्लिखित है, जिसके लिए यह आईएसओ सी से अलग है, जैसा कि ओपी द्वारा उद्धृत किया गया है।

Afaics हमें ISO C11 / 6.2.3 का सहारा लेना है और इसे आईएसओ सी ++ मानक के [diff.class] / 1 के साथ संयोजित करना है और C ++ के नए (नाम) नाम की अंतरिक्ष परिभाषा का एक सुसंगत और पूर्ण विवरण के लिए मानक है , इसलिए हम आईएसओ को कम करते हैं। C ++ मानक जैसे कि [basic.scope.hiding] , [class.name] / 2 , [stmt.label] / 1 , [cpp.replace] / 8 और इसी तरह यह देखने के लिए कि यह कैसे और कहां लागू होता है।

[Class.name] / 2

एक वर्ग घोषणा एक वर्ग के नाम को उस दायरे में पेश करती है जहाँ यह घोषित किया जाता है और किसी भी वर्ग, चर, फ़ंक्शन या उस नाम के अन्य घोषणा को एक संलग्न दायरे में छुपाता है। [...]

[Stmt.label] / 1

[...] लेबल का अपना नाम स्थान है और अन्य पहचानकर्ताओं के साथ हस्तक्षेप नहीं करते हैं [...]

[Cpp.replace] / 1

[...] मैक्रो नामों के लिए एक नाम स्थान है। [...]


1

C (6.2.3 पहचानकर्ताओं के नाम स्थान) में नाम रिक्त स्थान की धारणा निम्नलिखित तरीके से परिभाषित की गई है।

1 यदि किसी विशेष पहचानकर्ता की एक से अधिक घोषणा किसी अनुवाद इकाई के किसी भी बिंदु पर दिखाई देती है, तो वाक्यात्मक संदर्भ अलग-अलग संस्थाओं को संदर्भित करता है। इस प्रकार, पहचानकर्ताओं की विभिन्न श्रेणियों के लिए अलग-अलग नाम स्थान हैं, निम्नानुसार हैं:

- लेबल नाम (लेबल घोषणा और उपयोग के सिंटैक्स द्वारा विघटित);

- कीवर्ड्स स्ट्रक्चर, यूनियन या एनम के स्ट्रक्चर्स, यूनियनों और एनुमरेशन्स (किसी भी 32 का अनुसरण करके अस्वीकृत) के टैग;

- संरचनाओं या यूनियनों के सदस्य; प्रत्येक संरचना या संघ के पास अपने सदस्यों के लिए एक अलग नाम स्थान होता है (सदस्य या। -> ऑपरेटर के माध्यम से उपयोग करने के लिए उपयोग किए गए अभिव्यक्ति के प्रकार से असंबद्ध);

- अन्य सभी पहचानकर्ता, जिन्हें साधारण पहचानकर्ता कहा जाता है (साधारण घोषणाकर्ताओं में या गणन स्थिरांक के रूप में घोषित)।

इसलिए उदाहरण के लिए एक संरचना टैग नाम एक फ़ंक्शन नाम के साथ मेल खा सकता है क्योंकि वे विभिन्न नाम रिक्त स्थान से संबंधित हैं। जब आप एक संरचना टैग नाम के साथ एक संरचना निर्दिष्ट करते हैं जब आपको कीवर्ड का उपयोग करना होता है struct। इसलिए उदाहरण के लिए इन घोषणाओं में संघर्ष नहीं है।

struct s
{
    int s;
};

void s( void );

struct s s1;

इस कोड sमें संरचना का टैग नाम स्निपेट फ़ंक्शन नाम के साथ संघर्ष नहीं करता है s क्योंकि टैग नाम कीवर्ड के साथ निर्दिष्ट किया जाएगा struct

C ++ में आपको कीवर्ड के बिना स्ट्रक्चर टैग नामों का उपयोग करने की अनुमति है struct

उदाहरण के लिए

struct s
{
    int s;
};

s s;

एक सही कोड है। इस घोषणा में

s s;

घोषित पहचानकर्ता का sनाम संरचना नाम छुपाता है। तो अगर आप उदाहरण के लिए लिखेंगे

s s1;

तब कंपाइलर एक त्रुटि जारी करेगा क्योंकि इस कथन में s को ऊपर घोषित किए गए पहचानकर्ता के नाम के रूप में माना जाता है। अस्पष्टता को हल करने के लिए आपको कीवर्ड संरचना का उपयोग करने की आवश्यकता है

struct s
{
    int s;
};

s s;

struct s s1;

यह C ++ 20 मानक (6.3.1 घोषणा क्षेत्र और स्कोप) से निम्नलिखित उद्धरण में वर्णित है

4 एक एकल घोषणा क्षेत्र में घोषणाओं के एक सेट को देखते हुए, जिनमें से प्रत्येक एक ही अयोग्य नाम निर्दिष्ट करता है,

(४.१) - वे सभी एक ही इकाई को संदर्भित करेंगे, या सभी फ़ंक्शन और फ़ंक्शन टेम्पलेट को संदर्भित करेंगे; या

(४.२) - ठीक एक घोषणा एक वर्ग नाम या गणना नाम की घोषणा करेगा जो कि एक टाइप्डेफ़ नाम नहीं है और अन्य घोषणाएँ सभी एक ही चर, गैर-स्थैतिक डेटा सदस्य, या एन्यूमरेटर या सभी फ़ंक्शन और फ़ंक्शन टेम्पलेट को संदर्भित करेंगे। ; इस स्थिति में वर्ग नाम या गणना नाम छिपा हुआ है (6.3.10)। [ नोट: एक नेमस्पेस नाम या एक वर्ग टेम्पलेट का नाम अपने घोषणात्मक क्षेत्र में अद्वितीय होना चाहिए (१०.३.२, खंड १p)। - अंतिम नोट ]

जैसा कि आप उद्धरण से देख सकते हैं कि एक नाम स्थान अपने घोषणा क्षेत्र में अद्वितीय होना चाहिए। तो ये घोषणाएं

struct Foo { };
namespace Foo { } 

गलत हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.