2010-09-09 21 views
16

निम्नलिखित स्निपेट पर विचार करें:बेनामी नाम स्थान अस्पष्टता

void Foo() // 1 
{ 
} 

namespace 
{ 
    void Foo() // 2 
    { 
    } 
} 

int main() 
{ 
    Foo(); // Ambiguous. 
    ::Foo(); // Calls the Foo in the global namespace (Foo #1). 

    // I'm trying to call the `Foo` that's defined in the anonymous namespace (Foo #2). 
} 

मैं कैसे इस मामले में एक गुमनाम नाम स्थान के अंदर कुछ का उल्लेख कर सकते हैं?

उत्तर

16

आप नहीं कर सकते।

एक अनाम-नाम स्थान परिभाषा बर्ताव करता है जैसे कि वह

namespace unique { /* empty body */ } 
    using namespace unique; 
    namespace unique { namespace-body } 

द्वारा प्रतिस्थापित किया गया: मानक निम्न अनुभाग (§7.3.1.1, सी ++ 03) शामिल हैं जहां अनुवाद इकाई में अद्वितीय की सभी घटनाएं द्वारा समान पहचानकर्ता द्वारा प्रतिस्थापित की जाती हैं और यह पहचानकर्ता पूरे कार्यक्रम में अन्य सभी पहचानकर्ताओं से भिन्न होता है।

इस प्रकार आपके पास उस अद्वितीय नाम का संदर्भ देने का कोई तरीका नहीं है।

आप हालांकि तकनीकी रूप से निम्नलिखित के बजाय की तरह कुछ इस्तेमाल कर सकते हैं:

int i; 

namespace helper { 
    namespace { 
     int i; 
     int j; 
    } 
} 

using namespace helper; 

void f() { 
    j++; // works 
    i++; // still ambigous 
    ::i++; // access to global namespace 
    helper::i++; // access to unnamed namespace   
} 
+0

ठीक है, मानक कहता है कि क्या समझ में आता है। हालांकि, फिर एक अस्पष्टता क्यों है? अगर मैं अज्ञात नेमस्पेस में फू तक नहीं पहुंच पा रहा हूं, तो संकलक यह समझने में सक्षम होना चाहिए कि एकमात्र अन्य फू वैश्विक दायरे में से एक है। मुझे स्कोप रिज़ॉल्यूशन ऑपरेटर का बिल्कुल उपयोग नहीं करना चाहिए। समस्या के उस पहलू पर कोई विचार? – sharp02

+0

पुन: आपका संपादन - यह अब काफी कुछ है जो मैं कर रहा हूं, सिवाय इसके कि मैं वास्तविक लक्ष्य फ़ंक्शन पर जाने के लिए एक रैपर फ़ंक्शन का उपयोग करता हूं। – sharp02

+0

@ शार्प: उस दायरे में दो प्रतीक 'फू' हैं। समकक्ष स्थिति पर विचार करें: 'नामस्थान ए {int i; } नामस्थान बी {int i; } नामस्थान ए का उपयोग कर; नामस्थान बी का उपयोग कर; '। –

0

केवल असली तरीका कोड आप नाम स्थान के भीतर ही है कि नाम स्थान तक पहुंचना चाहते हैं डाल करने के लिए है। अन्यथा नामित नेमस्पेस को हल करने का कोई तरीका नहीं है, क्योंकि इसमें कोई पहचानकर्ता नहीं है, आप इसे संदिग्ध समाधान समस्या को हल करने के लिए दे सकते हैं।

यदि आपका कोड नेमस्पेस {} स्वयं ब्लॉक करता है, तो स्थानीय नाम वैश्विक स्तर पर प्राथमिकता प्राप्त करता है, इसलिए एक Foo() आपके नामस्थान के भीतर Foo() को कॉल करेगा, और एक :: Foo() कॉल करेगा वैश्विक दायरे पर नामस्थान।

4

जोर्ज मानक-complient, सही, सही, और सम्मानजनक जवाब देता है, मैं पेशकश करना चाहते हैं मेरी hacky एक - गुमनाम नाम स्थान भीतर एक और नाम स्थान का उपयोग करें:

#include <iostream> 

using namespace std; 

namespace 
{ 
namespace inner 
{ 
    int cout = 42; 
} 
} 

int main() 
{ 
    cout << inner::cout << endl; 
    return 0; 
} 
2

एकमात्र समाधान मैं इस बारे में सोच सकते हैं कि मौजूदा नेमस्पेस व्यवस्था को संशोधित नहीं किया गया है अज्ञात नेमस्पेस में किसी फ़ंक्शन में main को प्रतिनिधि करना है। (main अपने आप में एक वैश्विक समारोह (§3.6.1/1) होना आवश्यक है, तो यह एक गुमनाम नाम स्थान में नहीं हो सकता।)

void Foo() // 1 
{ 
} 

namespace 
{ 
    void Foo() // 2 
    { 
    } 
} 

namespace { // re-open same anonymous namespace 

    int do_main() 
    { 
     Foo(); // Calls local, anonymous namespace (Foo #2). 
     ::Foo(); // Calls the Foo in the global namespace (Foo #1). 

     return 0; // return not optional 
    } 

} 

int main() { 
    return do_main(); 
} 
0

बस स्थानीय नाम स्थान समारोह नाम बदलें।

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