2012-02-21 7 views
7

मेरे पास दो नामस्थान हैं जिनमें प्रत्येक के नाम पर एक ही कार्य है। यदि किसी नामस्थान से मैं उस फ़ंक्शन को कॉल करना चाहता हूं जो सर्वोत्तम से मेल खाता है। नेमस्पेसए में एक फ़ंक्शन से, यदि मैं माईफंक्शन (...) कहता हूं, तो निश्चित रूप से यह नेमस्पेसए में से एक का उपयोग करता है। हालांकि, अगर मैं 'नेमस्पेस बी :: माईफंक्शन' का उपयोग कर जोड़ता हूं, तो मैं उसके द्वारा वर्णित व्यवहार की अपेक्षा करता हूं। हालांकि, मैं वास्तव में जो देखता हूं वह यह है कि यह हमेशा नेमस्पेस फ़ंक्शन पाता है, भले ही मैं नेमस्पेस में हूं। हालांकि, अगर मैं भी एक उपयोग :: नेमस्पेसए जोड़ता हूं (भले ही मैं पहले से ही नेमस्पेस में हूं), यह काम करता है जैसा कि मैं उम्मीद करता हूं। एक प्रदर्शन नीचे है। क्या कोई यह समझा सकता है कि यह कैसे काम करता है?नेमस्पेस खोज ऑर्डर

#include <iostream> 

namespace NamespaceA 
{ 
    void DoSomething(); 
    void MyFunction(int object); 
} 

namespace NamespaceB 
{ 
    void MyFunction(float object); 
} 

namespace NamespaceA 
{ 
    void DoSomething() 
    { 
    using NamespaceA::MyFunction; // Note that without this line the lookup always fins the NamespaceB::MyFunction! 
    using NamespaceB::MyFunction; 

    MyFunction(1); 
    MyFunction(2.0f); 
    } 

    void MyFunction(int object) 
    { 
    std::cout << "int: " << object << std::endl; 
    } 
} 

namespace NamespaceB 
{ 
    void MyFunction(float object) 
    { 
    std::cout << "float: " << object << std::endl; 
    } 
} 

int main(int argc, char *argv[]) 
{ 
    NamespaceA::DoSomething(); 

    return 0; 
} 
+1

एक शब्द में, "खराब" । यदि आप 'माईफंक्शन' को अधिभारित करना चाहते हैं, तो बस एक ही नेमस्पेस में दोनों कार्यान्वयन करें, और कंपाइलर की ओवरलोडिंग तंत्र को पता लगाएं कि सबसे अच्छा मिलान कौन सा है। –

+0

क्या आपने इसे दो अलग-अलग कंपाइलरों में करने की कोशिश की है, या यह पता लगाने की कोशिश की है कि मानक व्यवहार क्या होना चाहिए? –

+0

@ डेविड थॉर्नले: यह _is_ मानक व्यवहार। यद्यपि आप सही हैं कि ओपी को क्रॉस-टेस्ट होना चाहिए था। –

उत्तर

0

मेरा मानना ​​है कि नेमस्पेस वैरिएबल के समान स्कोपिंग नियमों का उपयोग करते हैं। इसलिए यदि आपके पास स्थानीय नामस्थान है, तो बाहरी क्षेत्र में जाने से पहले लुकअप पहले वहां होंगे।

मुझे यकीन नहीं है कि नियमों के लिए नियम क्या हैं जहां आपने एक ही फ़ंक्शन नामों के साथ दो नामस्थान आयात किए हैं, लेकिन आपको हमेशा उस परिदृश्य में फ़ंक्शन कॉल को पूरी तरह से योग्यता के लिए अर्हता प्राप्त करनी चाहिए, कुछ नवाचार पर निर्भर रहने के बजाय उन नामस्थानों के लिए भाषा कार्यान्वयन का जो लोग परिचित नहीं हो सकते हैं।

2

इसे उस क्रम के साथ करना है जिसमें कार्यक्रम के विभिन्न हिस्सों को नाम खोजने के लिए देखा जाता है। आपके द्वारा उल्लेख की जाने वाली स्थिति के लिए, इसे संलग्न नामस्थान से पहले खोजे जाने वाले फ़ंक्शन के शीर्ष-स्तरीय ब्लॉक के दायरे से करना होगा। असल में, using घोषणा उस नाम को DoSomething के शीर्ष-स्तरीय दायरे में लाती है, और चूंकि उस दायरे को संलग्न नामस्थान स्कोप से पहले देखा जाता है, तो यदि मिलान करने वाला फ़ंक्शन वहां पाया जाता है, तो संलग्न नामस्थान स्कोप पर विचार नहीं किया जाता है।

मैंने आपके सामान में प्रासंगिक नहीं है (उदाहरण के लिए, यदि तर्क एक अंतर्निहित प्रकार नहीं था, तो विश्वास करें या नहीं, उस दायरे से नाम जहां उस प्रकार को परिभाषित किया गया था पूरी तरह से विचार किया जा सकता है। पूरी कहानी के लिए, अनुभाग 3.4 here देखें। यह बहुत डरावना है, लगभग 13 पृष्ठों को इन सभी चीजों का वर्णन करने के लिए; लेकिन जब तक आप वास्तव में उत्सुक नहीं हैं, तब तक इससे परेशान न हों, क्योंकि अधिकांश चीजें वहां हैं यह "जिस तरह से आप उम्मीद कर काम करता है", और अधिक या कम। उस दस्तावेज़ असली स्टैंडर्ड, लेकिन वास्तव में कुछ सुधार के साथ एक काम मसौदा नहीं है, तो यह मूल रूप से वास्तविक सी ++ स्टैंडर्ड प्लस कुछ bugfixes है।

+1

क्या यह प्रभावी रूप से पहला सी ++ 1x/सी ++ 2 एक्स ड्राफ्ट है? –

+0

हां, आप इसके बारे में सोच सकते हैं, लेकिन यह कुछ मामूली बगफिक्स के साथ "सी ++ 11" जैसा है। – chisophugis

+0

सी ++ 03 कुछ मामूली बगफिक्सेस के साथ सी ++ 98 था, और यह एक वास्तविक मानक था। –

0

लघु उत्तर: स्थानीय परिभाषित नाम और एक घोषणा-घोषणा द्वारा घोषित नाम nonlocal नाम छुपाता है।

विस्तृत जवाब:

आपका प्रश्न बहुत ही दिलचस्प है। मैंने उस प्रश्न के लिए सी ++ 98,03,11 के स्टैंडरेट नहीं खोले, लेकिन Bjarne Stroustrup's book

नामस्थान - एक नामित दायरा है।शब्दाडंबर दो तकनीकों का उपयोग कर समाप्त किया जा सकता:

  • का उपयोग कर एन एस :: एक्स का पर्याय बन गया बनाएँ; (घोषणा-घोषणा)
  • नामस्थान एनएस :: एक्स का उपयोग कर के साथ सभी चर के पर्याय का पर्याय बनें; (का उपयोग कर-निर्देश)

अपने प्रश्न का उत्तर यहाँ है:

Appendix B 10.1 
local definitions, and names defined with using-declaration hides 
the name of a non-local definitions. 

विपरीत स्थिति से बोनस:

इसके अलावा, अगर आप

using NamespaceA::MyFunction; 
using NamespaceB::MyFunction; 

करने के लिए परिवर्तन

using namespace NamespaceB; 

तो फिर तुम साथ खेलने के लिए

8.2.8.2 
Names explicitly declared in namespace (also made with using declaration) 
have priority over the names made available by using directives 

अतिरिक्त कोड के नीचे पाठ (पूर्णांक वस्तु) कॉल केवल शून्य myfunction के साथ स्थिति पाने की वजह से:

#include <iostream> 

// var in global namespace 
const char* one = "G_one"; 

// vars in named namespace 
namespace NS1 { 
    const char* one = "NS1_one"; 
    const char* two = "NS1_two"; 
    const char* three = "NS1_three"; 
} 

namespace NS2 { 
    const char* one = "NS2_one"; 
    const char* two = "NS2_two"; 
    const char* three = "NS2_three"; 
} 

int main(int argc, char *argv[]) 
{ 

    using namespace NS1;  // using-directive 
    using namespace NS2;  // using-directive 

    // const char* two = "L_two"; // local namespace 
    using NS2::two;    // using-declaration 

    // C++ rules 
    // Local names and names with using-declarations 
    // takes precedence over the name of the NS  
    std::cout << "two: " << two << std::endl; 

    //std::cout << "three: " << three << std::endl; // ambiguous symbol 

    // But the name in global-namespace does not have priority over imported name from namespace 
    //std::cout << "one: " << one << std::endl; // ambiguous symbol. Because wGlobal names does not have priority over 
    return 0; 
} 
संबंधित मुद्दे