2010-11-05 7 views
26

thisनेस्टेड नाम निर्दिष्टकर्ता क्या है?

से संबंधित मैं जानना चाहता हूं कि एक नेस्टेड नाम निर्दिष्टकर्ता क्या है? मैंने मसौदे में देखा लेकिन मैं व्याकरण को समझ सकता था क्योंकि मैंने अभी तक कोई कंपाइलर डिज़ाइन कक्षा नहीं ली है।

void S(){} 

struct S{ 
    S(){cout << 1;} 
    void f(){} 
    static const int x = 0; 
}; 

int main(){ 
    struct S *p = new struct ::S; 
    p->::S::f(); 

    S::x; 

    ::S(); // Is ::S a nested name specifier? 
    delete p; 
} 

उत्तर

33

::S एक योग्य-आईडी है।

योग्य-आईडी::S::f में, S:: एक नेस्टेड-नाम-विनिर्देशक है।

अनौपचारिक संदर्भ में , एक नेस्टेड-नाम-विनिर्देशकआईडी का हिस्सा है कि

  • शुरू होता है या तो या के बाद एक योग्य-आईडी के बहुत शुरुआत में प्रारंभिक स्कोप रिज़ॉल्यूशन ऑपरेटर (::) यदि कोई आईडी और
  • की शुरुआत में दिखाई देता है तो अंतिम स्कोप रिज़ॉल्यूशन ऑपरेटर के साथ समाप्त होता है योग्य-आईडी

बहुत अनौपचारिक , एक आईडी या तो एक योग्य-आईडी या एक अयोग्य-आईडी है। यदि आईडी एक योग्य-आईडी है, तो यह वास्तव में दो भागों से बना है: एक नेस्टेड-नाम विनिर्देशक अयोग्यता आईडी के बाद।

को देखते हुए:

struct A { 
    struct B { 
     void F(); 
    }; 
}; 
  • A एक अयोग्य-आईडी है।
  • ::Aयोग्य-आईडी है लेकिन इसमें नेस्टेड-नाम-विनिर्देशक नहीं है।
  • A::B एक योग्य-आईडी है और A:: एक नेस्टेड-नाम-विनिर्देशक है।
  • ::A::B एक योग्य-आईडी है और A:: एक नेस्टेड-नाम-विनिर्देशक है।
  • A::B::F एक योग्य-आईडी है और दोनों B:: और A::B::नेस्टेड-नाम-विनिर्देशक हैं।
  • ::A::B::F एक योग्य-आईडी है और दोनों B:: और A::B::नेस्टेड-नाम-विनिर्देशक हैं।

[1] यह काफी एक अयथार्थ वर्णन है। यह सादे अंग्रेजी में एक व्याकरण को बयान नहीं किया ...

+0

अधिक मैं इस बारे में सोचते हैं, और अधिक मैं इस लगता है कि मैं सिर्फ इस सीखा एक बहुत अच्छा जवाब नहीं है। मुझे नहीं पता कि इसे सरल शब्दों में कैसे समझाया जाए लेकिन फिर भी पूरी तरह से सही हो ... –

+1

लिटिल क्यू: 'ए :: बी' -> क्या मैं कह सकता हूं कि 'ए' ** क्वालीफाइंग निर्माण ** है और साथ ही साथ 'ए ::' एक नेस्टेड-नाम-विनिर्देशक है? –

6

एक नेस्टेड नाम स्थान विनिर्देशक है:

nested-name-specifier : 
    class-or-namespace-name::nested-name-specifier(optional) 

है, नामस्थान और classnames की एक गैर खाली सूची, प्रत्येक :: द्वारा पीछा किया, एक का प्रतिनिधित्व कार्यक्रम के समग्र "नामस्थान पेड़" में सापेक्ष शाखाकरण। उदाहरण के लिए, my_namespace::, my_namespace::inner_namespace::, my_namespace::my_class::, और my_class::

नोट विशेष रूप से अंतर से:

qualified-namespace-specifier : 
    ::(optional) nested-name-specifier(optional) class-or-namespace-name 

कि एक नेस्टेड-नाम-विनिर्देशक निरपेक्ष (:: उपसर्ग के साथ वैश्विक विस्तार का उल्लेख करने के लिए) नहीं किया जा सकता है, एक योग्य-नाम स्थान-विनिर्देशक हो सकता है, जबकि , लेकिन :: के साथ समाप्त नहीं होता है।

अपने उदाहरण में, ::S समारोह ::S(), और नहीं struct (precendence वाले नियम के लिए सवाल आप अपने प्रश्न के शुरू में से जुड़ा हुआ में Stackoverflow पर यहां चर्चा की गई) पर ले कर जाता है, इसलिए यह एक नेस्टेड नाम नहीं है विनिर्देशक।

3

अच्छा सवाल! मैंने कुछ नया शोध और प्रयोग किया।

आप अपनी टिप्पणी में सही हो, ::S(); //Is ::S a nested name specifier <-- Yes, Indeed!

आप इसे सराहना करते हैं जब आप नामस्थान का निर्माण शुरू आएगा। वेरिएबल्स में नामस्थानों में समान नाम हो सकते हैं और :: ऑपरेटर उन्हें अलग करता है। नेमस्पेस एक अर्थ में कक्षाओं की तरह हैं, अमूर्तता की एक और परत। मैं आपको नामस्थानों के साथ बोर नहीं करना चाहता हूं। आप इस उदाहरण में नेस्टेड नाम विनिर्देशक सराहना नहीं हो सकता है ... यह एक पर विचार करें:

#include <iostream> 
using namespace std; 

int count(0);     // Used for iteration 

class outer { 
public: 
    static int count;   // counts the number of outer classes 
    class inner { 
    public: 
     static int count;  // counts the number of inner classes 
    }; 
}; 

int outer::count(42);   // assume there are 42 outer classes 
int outer::inner::count(32768); // assume there are 2^15 inner classes 
           // getting the hang of it? 

int main() { 
    // how do we access these numbers? 
    // 
    // using "count = ?" is quite ambiguous since we don't explicitly know which 
    // count we are referring to. 
    // 
    // Nested name specifiers help us out here 

    cout << ::count << endl;  // The iterator value 
    cout << outer::count << endl;   // the number of outer classes instantiated 
    cout << outer::inner::count << endl; // the number of inner classes instantiated 
    return 0; 
} 

सूचना है कि मैं ::count जहाँ मैं सामान्य रूप से उपयोग किया जा सकता था count इस्तेमाल किया। ::count वैश्विक नामस्थान को संदर्भित करता है।

अपने मामले में

तो, के बाद से एस() ग्लोबल नेम स्पेस में है (यानी यह आप new struct ::S या new struct S इस्तेमाल कर सकते हैं एक ही फाइल या एक शामिल फ़ाइल या कोड के किसी भी भाग में जहां यह namespace <name_of_namespace> { } द्वारा छा नहीं कर रहा है में घोषित है,; जो भी आप पसंद करते हैं।

रूप में मैं इस सवाल का जवाब देने उत्सुक था, इसलिए यदि आप एक अधिक विशिष्ट और सीखा जवाब है, कृपया शेयर :)

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