2016-07-30 8 views
7

मैं एक std :: मैप घोषित करने के लिए सही वाक्यविन्यास के साथ मदद पूछना चाहता हूं जिसका मैप किए गए प्रकार टेम्पलेट वर्ग का एक आंतरिक वर्ग है।टेम्पलेट वर्ग 'आंतरिक वर्ग के मानचित्र इटरेटर के लिए सही वाक्यविन्यास?

कृपया # if/# else block के नीचे दिए गए कोड में खोजें। "#if 1" ब्लॉक में टेम्पलेट क्लास बाहरी है जिसमें आंतरिक कक्षा आंतरिक शामिल है। बाहरी फ़ंक्शन फ़ंक्शन को परिभाषित करता है जो एक std मैप लेता है जिसका mapped_type इनर प्रकार का होता है।

#include <map> 

#if 1 
template<typename C, typename T> 
class Outer 
{ 
    public: 
     Outer(const C& c, const T& t){} 
     virtual ~Outer(){} 

     class Inner 
     { 
      public: 
       Inner(){} 
       Inner(T t){} 
       virtual ~Inner(){} 

      protected: 
       T mT; 
     }; 

     void Func(std::map<C, Inner>& rMap); 

    protected: 
     std::map<C, Inner> mMap; 
}; 

template<typename C, typename T> 
void Outer<C, T>::Func(std::map<C, Outer::Inner>& rMap) 
{ 
    std::map<C, Inner>::iterator iter; 

    for (iter = rMap.begin(); iter != rMap.end(); ++iter) 
    { 
     mMap[iter->first] = iter->second; 
    } 
} 

#else 

class Outer 
{ 
    public: 
     Outer(const int& i, const double& d){} 
     virtual ~Outer(){} 

     class Inner 
     { 
      public: 
       Inner() : mD(0){} 
       Inner(const double d) : mD(d){} 
       virtual ~Inner(){} 

      protected: 
       double mD; 
     }; 

     void Func(std::map<int, Inner>& rMap); 

    protected: 
     std::map<int, Inner> mMap; 
}; 

void Outer::Func(std::map<int, Inner>& rMap) 
{ 
    std::map<int, Inner>::iterator iter; 

    for (iter = rMap.begin(); iter != rMap.end(); ++iter) 
    { 
     mMap[iter->first] = iter->second; 
    } 
} 

#endif 

int main() 
{ 
    return 0; 
} 

संकलन std :: नक्शा iterator की घोषणा पर बाहरी :: समारोह (...) में विफल रहता है, इस लाइन यानी:

std::map<C, Inner>::iterator iter; 

मैंने कोशिश की है, लेकिन समझ नहीं क्या कोड की रेखा के साथ गलत है।

तुलना/विपरीत के लिए, "#else" ब्लॉक में समान प्रकृति का गैर-टेम्पलेट कोड होता है। यह कोड संकलित करता है।

संकलन त्रुटि और जी ++ संस्करण हैं:

>g++ main.cpp 
main.cpp: In member function ‘void Outer<C, T>::Func(std::map<C, Outer<C, T>::Inner, std::less<_Key>, std::allocator<std::pair<const C, Outer<C, T>::Inner> > >&)’: 
main.cpp:31: error: expected ‘;’ before ‘iter’ 
main.cpp:33: error: ‘iter’ was not declared in this scope 

>g++ --version 
g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-11) 
Copyright (C) 2010 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

किसी भी मदद के लिए धन्यवाद।

+0

'typename std :: map :: iterator iter;' – nshct

+0

संभावित डुप्लिकेट [मुझे कहां और क्यों "टेम्पलेट" और "टाइपनाम" कीवर्ड डालना है?] (Http://stackoverflow.com/questions/610245/जहां-और-क्यों-do-i-have-to-put-the-template-and-typename-keyword) – Oktalist

उत्तर

9

चूंकि Inner आपके टेम्पलेट Owner<C, T> का सदस्य है, यह dependent name बन जाता है। इससे पहचानकर्ता iterator का कारण बनता है, जो इस मामले में std::map<C, Inner> का सदस्य है, जो एक आश्रित नाम बनने के लिए भी है।

यह कीवर्ड typename उपयोग करने के लिए आप मजबूर करता, नियमों के अनुसार:

typename std::map<C, Inner>::iterator iter; 
~~~^~~~~ 

इसका कारण यह है संकलक यकीन है के बाद से यह नहीं है कि आपके वर्ग के अंदर कुछ निर्माणों का मतलब यह नहीं हो सकता है C के लिए इस्तेमाल किया सटीक प्रकार और T पता अभी तक:

एक टेम्पलेट की परिभाषा (दोनों वर्ग टेम्पलेट और समारोह टेम्पलेट) के अंदर, अर्थ ओ एफ कुछ संरचनाएं एक तात्कालिकता से दूसरे में भिन्न हो सकती हैं। विशेष रूप से, प्रकार और अभिव्यक्ति प्रकार के टेम्पलेट पैरामीटर और गैर-प्रकार के टेम्पलेट पैरामीटर के मानों पर निर्भर हो सकती हैं।

typename कीवर्ड का उपयोग संकलक को यह बताने के लिए किया जाता है कि जिस प्रतीक को आप एक्सेस कर रहे हैं वह वास्तव में एक प्रकार का उपनाम/प्रकार है।

+1

मैं वहां मौजूद ज्ञान के फ़ॉन्ट पर आश्चर्यचकित हूं। धन्यवाद। – StoneThrow

+0

ईमानदार होने के लिए, आपके द्वारा नोट किए गए लिंक पर स्पष्टीकरण मेरे सिर से ऊपर चला गया। यदि आप इस परिदृश्य से बहुत परिचित हैं, तो क्या आप इसे सरल शब्दों में समझा सकते हैं? जब आप कहते हैं "टाइपनाम कीवर्ड का उपयोग संकलक को बताने के लिए किया जाता है कि जिस प्रतीक को आप एक्सेस कर रहे हैं वह वास्तव में एक प्रकार का उपनाम/प्रकार है", इस संदर्भ में "प्रतीक" क्या है? आंतरिक वर्ग? स्पष्टीकरण के मेरे विश्लेषण के आधार पर, मुझे अस्पष्ट नहीं है कि इस स्थिति (आंतरिक कक्षाओं) के लिए इस समाधान की आवश्यकता क्यों है, लेकिन "गैर-आंतरिक" वर्गों के साथ इसकी आवश्यकता नहीं है। यदि आपके पास गहन स्पष्टीकरण है तो सराहना करें, लेकिन यदि कोई चिंता न हो तो कोई चिंता न करें। धन्यवाद। – StoneThrow

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