2011-03-04 13 views
18

मैं एसटीएल लाइब्रेरी सीखने की कोशिश कर रहा हूं और मुझे एक अजीब समस्या है। इस कोड को पूरी तरह से संकलित:टेम्पलेट कार्यों में वेक्टर इटरेटर के बारे में प्रश्न

template <class T> 
void Show2(vector<T> myvec) 
{ 
    vector<T>::iterator it; 
    cout << "Vector contains:"; 
    for(it = myvec.begin(); it < myvec.end(); it++) 
    { 
     cout << " " << *it; 
    } 
    cout << endl; 
} 

त्रुटि है:

void Show(vector<int> myvec) 
{ 
    vector<int>::iterator it; 
    cout << "Vector contains:"; 
    for(it = myvec.begin(); it < myvec.end(); it++) 
    { 
     cout << " " << *it; 
    } 
    cout << endl; 
} 

जबकि यह एक मेरे संकलन समय पर एक त्रुटि संदेश देता है

$ g++ hello.cpp 
hello.cpp: In function ‘void Show2(std::vector<T, std::allocator<_Tp1> >)’: 
hello.cpp:19: error: expected ‘;’ before ‘it’ 
hello.cpp:21: error: ‘it’ was not declared in this scope 

यह एक बहुत ही सरल गलती लगता है, लेकिन मुझे यह नहीं मिला।

+0

संभव डुप्लिकेट http://stackoverflow.com/questions/610245/where-to-put-the-template-and-typename- ऑन-आश्रित-नाम) – fredoverflow

+2

संभावित रूप से बहुत पहले उत्तर दिया गया था, लेकिन टाइपनाम/आश्रित नामों की खोज करना मुश्किल है यदि आपको नहीं पता कि ऐसे शब्द मौजूद हैं – Erik

+0

@FredOverflow यह एक बहुत अच्छा लिंक है और मैं शायद इसे पढ़ूंगा अभी। लेकिन, जैसे @Erik ने कहा कि अगर आपको पता नहीं है कि अंतर्निहित समस्या क्या है, तो आप कई विशिष्ट शर्तों की खोज करेंगे और कभी भी अधिक सामान्य समस्या के लिए नहीं खोजेंगे। मैंने इटरेटर्स, टेम्पलेट्स, वेक्टर, एसटीएल, ... के लिए कई खोज कीं और कुछ भी नहीं मिला, मुझे पता नहीं था कि कीवर्ड 'टाइपनाम' अस्तित्व में था (:(हाँ, मैं नोब हूं: पी)। मैंने सोचा कि यह सिर्फ एक बेवकूफ वाक्यविन्यास त्रुटि। –

उत्तर

24

आप typename vector<T>::iterator it कहने के लिए की जरूरत है।

एक और नोट पर, आप मूल्य से vector पास कर रहे हैं। इसका मतलब है कि पूरे vector फ़ंक्शन कॉल में कॉपी हो जाता है। void Show(vector<T> const &myvec) और const_iterator का उपयोग करना बुद्धिमान होगा।

+4

यदि वह एक कॉन्स रेफरी पास करता है, तो आपको उसे कॉन्स्ट_इटरेटर का उपयोग करने के लिए भी बताना होगा। – Erik

+0

@Erik: बिल्कुल सही, मेरी पोस्ट अपडेट की गई। टिप के लिए –

+0

धन्यवाद। –

2

कुछ कंपेलरों को सदस्य नाम क्या है और टेम्पलेट के अंदर, एक प्रकार का नाम क्या है, इसका पता लगाने में समस्याएं हैं। अपने टेम्पलेट फ़ंक्शन बॉडी की पहली पंक्ति में ऐसा कुछ लिखने का प्रयास करें।

typename vector<T>::iterator it;

+1

सही है, लेकिन यह वास्तव में एक संकलक समस्या नहीं है। सी ++ मानक अनिवार्य है कि संकलक एक आश्रित नाम को सदस्य के रूप में एक टेम्पलेट में मानता है, न कि एक प्रकार, जब तक * टाइपनाम * का उपयोग नहीं किया जाता है। – decltype

+1

यह "कुछ कंपाइलर" नहीं है। व्याकरण बस इसे अनुमति नहीं देता है। "कुछ कंपाइलर" टाइपरनाम के साथ पुनः प्रयास करके प्रोग्रामर को दोबारा अनुमान लगा सकते हैं यदि पार्सिंग इसके बिना विफल रहता है और इस प्रकार * कुछ * गलत मामलों को संकलित करता है। –

+0

आप सही हैं। मुद्दा लेना! – CygnusX1

0

शायद यह typename vector<T>::iterator it; का उपयोग कर काम करता है आपका कंपाइलर यह नहीं जानता कि एक आंतरिक कक्षा इटरेटर है।

typename vector<T>::iterator it; 

इस संकलक कि vector<T>::iterator एक प्रकार के रूप में व्यवहार किया जाना चाहिए बताता है, कुछ यह कल्पना नहीं कर सकते क्योंकि iterator क्या T है पर निर्भर है:

0

पहला उदाहरण पैरामीटर में, हालांकि यह एक टेम्पलेट का उपयोग करता है, एक टेम्पलेट नहीं है, यह एक पूरी तरह से परिभाषित वर्ग है (vector<int>)

बाद उदाहरण में पैरामीटर प्रकार टी पर एक टेम्पलेट है और इस प्रकार की आवश्यकता है typeName (के [कहाँ "टेम्पलेट" और आश्रित के नाम पर "typename" डाल करने के लिए]

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