2011-12-01 5 views
7

मैंने अज्ञात नामस्थान का परीक्षण करने के लिए नीचे इस डमी कोड को आजमाया।नामस्थानों का नाम एक ही चर के साथ नामित नेमस्पेस है

मैं मैं थोड़ा इस बारे में उलझन में हूँ निम्नलिखित उत्पादन

ctor 1 
ctor 0 
3 
5 

है।

  1. मैं संकलक से एक त्रुटि की उम्मीद कर कह रही है कि यह a::m_a के बारे में एक अस्पष्टता को हल नहीं कर सकता था। इसके बजाय यह हमेशा कम घोंसला को संदर्भित करता है। क्या यह हमेशा मामला है? सी ++ के नियम क्या हैं?
  2. ऐसा लगता है कि संकलक फ़ाइल पर लिखे गए आदेश के बाद परिवर्तनीय सीएमओओबीजे बनाता है। क्या यह हमेशा मामला है?
  3. main() से सबसे नेस्टेड m_a परिवर्तनीय तक पहुंचने का कोई तरीका है?
class CMyObj{  
    public: 
    CMyObj(int a){std::cout << "ctor " << a << std::endl; } 
}; 
namespace a{ 
     namespace{ 
      int m_a=4; 
      int m_b=5; 
      CMyObj m_obj(1); 
     } 
} 
namespace a{ 
     int m_a=3; 
     CMyObj m_obj(0); 
} 
int main(){ 
     std::cout << a::m_a << std::endl; // which one? 
     std::cout << a::m_b << std::endl; // how this is possible? 
     return 0; 
} 

उत्तर

3

मेरे पास शब्द की जांच करने के लिए मेरे साथ सी ++ 03 मानक नहीं है, इसलिए मैं एफडीआईएस एन 32 9 0 से उद्धरण दूंगा। मुझे लगता है कि इस सवाल का जवाब 3.4.3.2/2 में योग्य नाम देखने नियमों में पाया जाता है:

For a namespace X and name m, the namespace-qualified lookup set S(X,m) is defined as follows: Let S0(X,m) be the set of all declarations of m in X and the inline namespace set of X (7.3.1). If S0(X,m) is not empty, S(X,m) is S0(X,m); otherwise, S(X,m) is the union of S(Ni,m) for all namespaces Ni nominated by using-directives in X and its inline namespace set.

अब, याद रखें कि अज्ञात नाम स्थान एक निर्देश का उपयोग कर के साथ एक विशिष्ट नामित नाम स्थान है।

+0

वह अंतिम वाक्य कुंजी है। धन्यवाद। –

+0

हाय जीन! आपके रीप्ले के लिए बहुत बहुत धन्यवाद (कुछ देरी के साथ आ रहा है)! –

1

मैं कल्पना में सही परिभाषाओं को खोजने के लिए समय लेना चाहिए, लेकिन आप एक गुमनाम (बेनाम) नाम स्थान है जब, संकलक वास्तव में एक घायल नाम उत्पन्न करता है। जब आप

a::m_b 
दूसरा std::cout बयान में

लिखते हैं, संकलक हो जाता है ताकि आप इसे उपयोग कर सकते हैं घायल नाम प्रतिस्थापन है। जीन Bushuyev के बाद के जवाब से शामिल:

Now, remember that unnamed namespace is a uniquely named namespace with a using directive.

टकराने नाम के मामले में, संकलक जानता है क्या a::m_a मतलब है, तो यह है कि उपयोग करता है। यह नामस्थान के शीर्ष स्तर पर एक है। मुझे नहीं लगता कि इस बिंदु पर m_a की अनाम नामस्थान प्रतिलिपि पाने का कोई तरीका है।

यह पृष्ठ नामस्थानों को समझाने का एक अच्छा काम करता है। Winterdom: On C++ Namespaces

+0

"मुझे नहीं लगता कि इस बिंदु पर m_a की अनामित नामस्थान प्रतिलिपि पाने का कोई तरीका है।" - ऐसा लगता है कि आप एक एक्सेसर फ़ंक्शन/उपनाम जोड़ने के लिए नामित नेमस्पेस को फिर से खोल सकते हैं। – visitor

1

इस सरलीकृत कोड पर पहले देखो (और मेरी सरलीकृत व्याख्या, आप जानकारी के लिए §3.4.3.2 पढ़ सकते हैं):

namespace a 
{ 
    int x; 
} 

int main() 
{ 
    int i = a::x; 
} 

पर विचार करें क्या होता है जब हम a::x का कहना है। सबसे पहले संकलक की सभी घोषणाओं को a में बताता है। यदि यह एक अस्पष्ट x पाता है, तो यह सफलतापूर्वक समाप्त हो जाता है। अन्यथा यह उपयोग-निर्देश द्वारा घोषित नामस्थानों की पुनरावृत्ति की खोज करता है। यदि इसका नतीजा कभी नहीं मिलता है, तो कार्यक्रम खराब हो गया है।

namespace a 
{ 
    int x; 
} 

namespace b 
{ 
    using namespace a; 
} 

int main() 
{ 
    int i = b::x; 
} 

यहाँ, यह b में x नहीं मिल रहा है, तो यह (क्योंकि का उपयोग कर-निर्देश का) नाम स्थान a खोज करता है और यह पाता है।अब यह समझ बनाने चाहिए क्यों यह अस्पष्ट नहीं है:

namespace a 
{ 
    int x; 
} 

namespace b 
{ 
    using namespace a; 
    int x; 
} 

int main() 
{ 
    int i = b::x; 
} 

यहाँ यह b में x पाता है और समझता है a कभी नहीं। अब बस विचार है कि एक अनाम नाम स्थान वास्तव में एक अद्वितीय अज्ञात नाम के साथ सिर्फ एक नाम का स्थान:

namespace b 
{ 
    namespace 
    { 
     int x; 
    } 

    // this is what an unnamed namespace expands to (in exposition) 
    namespace __unique__ {} 
    using namespace __unique__; 

    namespace __unique__ 
    { 
     int x; 
    } 

    int x; 
} 

int main() 
{ 
    int i = b::x; 
} 
पहले की तरह

, b में x अनाम नाम स्थान पर विचार किए बिना पाया जाता है। आपका कोड समान है।

+0

मुझे आपकी विस्तृत व्याख्या पसंद है। –

0

कोई अस्पष्टता नहीं है क्योंकि namespace::<unnamed>::m_a का दायरा बाहरी नामस्थान (namespace::a) है। मुख्य कार्य के भीतर namespace::<unnamed>::m_a तक पहुंचने का कोई तरीका नहीं है और इसीलिए कोई अस्पष्टता नहीं है। निम्नलिखित कोड को संकलित करने का प्रयास करें और आप त्रुटि मिलेगी:

namespace ns{ 
    namespace { 
    int a = 2; 
    } 
    int a = 3; 
    int c = a; 
} 

वैश्विक एक ही अनुवाद इकाई में रहने वाले चर क्रम में वे घोषित किया गया है में प्रारंभ कर दिया जाएगा। विभिन्न अनुवाद इकाइयों में घोषित वैश्विक चर के प्रारंभिक क्रम को अपरिभाषित किया गया है।

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