2013-08-08 11 views
7

मुझे एक समस्या है जो नेस्टेड नेमस्पेस और टेम्पलेटेड कक्षाओं को आमंत्रित करती है। मैं टेस्ट केस बनाने में भी सक्षम था जो वास्तविक कोड के समान त्रुटि उत्पन्न करता है, लेकिन थोड़ा और पठनीय है।नेस्टेड नेमस्पेस और संदिग्ध प्रतीक

namespace A 
{ 
    namespace B 
    { 
     namespace C1 
     { 
     struct SMeasResult{}; 
     } 
     namespace C2 
     { 
     struct SMeasResult{}; 
     } 
    } 
} 

namespace C1Test 
{ 
    using namespace A::B::C1; 

    template<typename T> 
    class Fook 
    { 
    public: 

     void Yu() 
     { 
     SMeasResult Field; 
     } 
    }; 
} 

namespace C2Test 
{ 
    using namespace A::B::C2; 

    template<typename T> 
    class Fook 
    { 
    public: 

     void Yu() 
     { 
     SMeasResult Field; 
     } 
    }; 
} 

void m(){ 
    C1Test::Fook<int> yu; 
    C2Test::Fook<int> me; 

    yu.Yu(); 
    me.Yu(); 
} 

विशिष्ट त्रुटि इस प्रकार है::

निम्नलिखित कोड 2010 मंच टूलसेट साथ VS2012 का उपयोग कर संकलन एक त्रुटि का कारण बनता है

1>------ Build started: Project: MultiVicomTest (Visual Studio 2010), Configuration: Debug Win32 ------ 
1> test.cpp 
1>c:\code\test.cpp(27): warning C4101: 'Field' : unreferenced local variable 
1>   c:\code\test.cpp(26) : while compiling class template member function 'void C1Test::Fook<T>::Yu(void)' 
1>   with 
1>   [ 
1>    T=int 
1>   ] 
1>   c:\code\test.cpp(49) : see reference to class template instantiation 'C1Test::Fook<T>' being compiled 
1>   with 
1>   [ 
1>    T=int 
1>   ] 
1>c:\code\test.cpp(43): error C2872: 'SMeasResult' : ambiguous symbol 
1>   could be 'c:\code\test.cpp(11) : A::B::C2::SMeasResult' 
1>   or  'c:\code\test.cpp(7) : A::B::C1::SMeasResult' 
1>   c:\code\test.cpp(42) : while compiling class template member function 'void C2Test::Fook<T>::Yu(void)' 
1>   with 
1>   [ 
1>    T=int 
1>   ] 
1>   c:\code\test.cpp(50) : see reference to class template instantiation 'C2Test::Fook<T>' being compiled 
1>   with 
1>   [ 
1>    T=int 
1>   ] 
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 

मैं क्यों प्रतीक समझ में नहीं आता 'SMeasResult' कंपाइलर के लिए अस्पष्ट होगा, क्योंकि इसका उपयोग एक अलग नामस्थान में किया जाता है। मुझे अब तक क्या पता चल सकता है, यह समस्या केवल तभी दिखाई देती है जब कक्षाएं कक्षाएं हों। जब टेम्पलेट परिभाषा हटा दी जाती है तो वही समस्या प्रकट नहीं होती है।

क्या कोई मुझे बता सकता है कि मैंने कुछ गलत किया है?

+1

मुझे यकीन है कि यह एक बग है। जीसीसी और क्लैंग इसे ठीक से संकलित करते हैं और मैं नहीं देख सकता कि यह अस्पष्ट क्यों होगा। – jrok

+1

एमएसवीसी ने सी ++ 98 के बाद से भाषा मानकों द्वारा अनिवार्य रूप से टेम्पलेट्स में उपयोग किए गए नामों के लिए दो चरण लुकअप को कभी भी लागू नहीं किया है। यह बग सबसे अधिक संभावना है जिसके परिणामस्वरूप। – Casey

उत्तर

2

यह वास्तव में मेरे लिए एक कंपाइलर बग जैसा दिखता है। जब आप मानते हैं कि अस्पष्टता के बिना संकलित फ़ंक्शन का C1Test संस्करण, मुझे संदेह है कि किसी भी तरह namespace C1Test के भीतर उपयोग नामस्थान C2Test नामस्थान पर भी सीमित है।

यह इस तथ्य से और पुष्टि करता है कि जी ++ 4.4 और 4.5 दोनों इस कोड को ठीक कर सकते हैं।

+1

हाँ, उपयोग दृश्य पर लीक किया गया है और जी ++ में नहीं। चूंकि मैं इस कीवर्ड का बड़ा प्रशंसक नहीं हूं, इसलिए मुझे नहीं पता कि इसके बारे में मानक क्या कह रहे हैं। – Uman

+1

दिलचस्प बात यह है कि 'सी 1 टेस्ट' से पहले 'सी 2 टेस्ट' से पहले कोड को फिर से "अस्पष्टता" के परिणामस्वरूप * * सी 2 टेस्ट 'के अंदर 'SMeasResult' के लिए रिपोर्ट किया जा रहा है। तथ्य यह है कि 'सी 1' में घोषणा 'सी 2' से पहले प्रकट होती है जो उपयोगों के क्रम से अधिक महत्वपूर्ण प्रतीत होती है। – Casey

+0

मेरी गलती - यह टेम्पलेट इंस्टॉलेशन का ऑर्डर है जो महत्वपूर्ण है, घोषणाओं में से कोई भी नहीं। तत्काल होने वाला दूसरा टेम्प्लेट 'सी 1', 'सी 2', 'सी 1 टेस्ट' या 'सी 2 टेस्ट' के घोषणा आदेश के बावजूद त्रुटि के लिए" दोषी "हो जाता है। – Casey

0

ए :: बी :: सी 1 :: SMeasResult का उपयोग करके का उपयोग करने का प्रयास करें; ए :: बी :: सी 2 :: SMeasResult का उपयोग कर और ; आपके सी 1 टेस्ट और सी 2 टेस्ट नेमस्पेस में। यह मुद्दा हल करता है।

बीटीडब्ल्यू आपको इतने सारे नामस्थानों की आवश्यकता क्यों है? एसटीएल बहुत बड़ा है, लेकिन यह केवल 1 नामस्थान - std का उपयोग करता है।

+0

बूस्ट भी बड़ा है और यह कई नामस्थानों का उपयोग करता है;) –

+0

इस विशिष्ट मामले में, हमारे पास एक बड़ा कोडबेस है जिसमें विभिन्न प्रकार की रेडियो तकनीकों से संबंधित कोड शामिल है। हम इसी वर्ग को नामस्थानों में स्थानांतरित करना चाहते हैं जो उनके द्वारा प्रस्तुत की जाने वाली तकनीक जैसा दिखता है, इसलिए कई नामस्थानों की आवश्यकता है। कई अन्य प्लेटफ़ॉर्म (.NET, Java) को एकीकृत करने के कारण, हमने उनके समान एक तरीका चुना है (बस उन प्लेटफ़ॉर्म में बड़ी संख्या में नामस्थानों के बारे में सोचें)। – Simon

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