2011-08-10 6 views
6

मैं आमतौर पर इस तरह से एक वेक्टर से अधिक पुनरावृति:वेक्टर के तत्वों पर पुनरावृत्ति करते समय सूचकांक प्रकार क्या होना चाहिए?

for (int i = 0; i < myVector.size(); i++) { 
    Element* e = myVector[i]; 
} 

लेकिन फिर संकलक आमतौर पर मुझे यह चेतावनी देता है:

warning: C4018: '<' : signed/unsigned mismatch 

तो अगर एक int सही नहीं है, किस प्रकार का सूचकांक होना चाहिए? वेक्टर :: आकार() एक "size_type" प्रकार का प्रतीत होता है, लेकिन मैं अधिक अर्थपूर्ण प्रकार का उपयोग करना चाहता हूं। कोई उपाय?

+5

इंडेक्स का उपयोग करने के बजाय, इटरेटर्स का उपयोग करने पर विचार करें। –

उत्तर

13

आपको std::vector<T>::size_type का उपयोग करना चाहिए। इसका हस्ताक्षर अभिन्न प्रकार। इसका आमतौर परsize_t जैसा ही है।

size_type और size_t के बीच अंतर जानने के लिए, इस विषय देखें:

1. इसी तरह, आप std::string::size_type, std::list<T>::size_type, std::deque<T>::size_type, std::set<T>::size_type, और इतने पर उपयोग कर सकते हैं। लगभग सभी मानक कंटेनर size_type नामक एक नेस्टेड प्रकार को परिभाषित करते हैं।


यह तर्क कर सकते हैं कि आप इटरेटर बजाय सूचकांक उपयोग करना चाहिए। लेकिन मैं यह भी देख सकते हैं कि कुछ समय इटरेटर बनाता है के लिए लूप बहुत व्यापक क्षैतिज, इस देखें:

for(std::vector<std::vector<std::string> >::iterator it = v.begin(); it != v.end(); ++it) 
{ 
} 

यह नहीं लगती है। यह वास्तव में कभी-कभी परेशान होता है। ऐसी परिस्थितियों में, कुछ प्रोग्रामर इंडेक्सइटरेटर से अधिक पसंद करते हैं।

सी ++ 0x, इटरेटर को अधिक मूर्खतापूर्ण बना दिया गया है। अब आप वाक्य रचना बोझिल बनाने के बिना इटरेटर उपयोग कर सकते हैं:,

for(auto it = v.begin(); it != v.end(); ++it) 
{ 
} 

या और भी बेहतर उपयोग करते हुए रेंज आधारित पाश के लिए:

for(auto & item : v) 
{ 
} 
2

संकलक चेतावनी देता है क्योंकि आपके पूर्णांक हस्ताक्षरित किया गया है लेकिन आकार() आकार के आकार के एक हस्ताक्षरित int देता है। आप इस तरह के मेल नहीं खाते हैं क्योंकि यदि आपका int नकारात्मक है तो यह सिरदर्द का कारण बन सकता है। आप size_t का उपयोग कर इन सब से बच सकते हैं।

0

आप कर रहे हैं सिर्फ यात्रा के लिए उपयोग करते हैं, तो आप उपयोग कर सकते हैं:

typedef std::vector<Element*> ElementContainer; 
    ElementContainer myVector(3); 

    for (ElementContainer::const_iterator cit = myVector.begin();cit != myVector.end(); ++cit) 
    { 
     Element* e = *cit; 
    } 

यह थोड़ा अधिक vector<> से दूसरे कंटेनर के लिए बदलने के मजबूत होने का लाभ है।

-1

बस unsigned का उपयोग करें।size_t के साथ आपको कभी याद नहीं है कि सही हेडर क्या शामिल है, और vector<T>::size_type के साथ आप बहुत अधिक टाइपिंग समाप्त करते हैं। सभी व्यावहारिक उद्देश्यों के लिए वे एक ही बात हैं, बस typedef एक दर्जन बार संपादित करें।

+0

एक विशिष्ट 64 बिट मशीन पर, 'std :: size_t' और' unsigned' * एक ही चीज़ नहीं हैं। –

+0

@ डेविड, 64 बिट्स मशीन पर अलग क्या होगा? यदि मैं 'size_t' के बजाय 'हस्ताक्षरित int' का उपयोग करता हूं तो क्या मैं किसी भी समस्या में भाग सकता हूं? –

+0

यदि वेक्टर में आइटमों की संख्या 42 9 4 9 672 9 5 से अधिक हो जाती है, तो आप 'हस्ताक्षरित int' का उपयोग कर समस्याओं में भाग लेंगे। अगर आपको लगता है कि आपका एप्लिकेशन वेक्टर रखने के करीब भी आ सकता है, तो यह बड़ा होगा कि आप इसे पहले से ही जानते होंगे। ज्यादातर मामलों में आपको 'std :: size_t' के बजाय 'हस्ताक्षरित int' का उपयोग करने में कोई समस्या नहीं होगी। –

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