2009-03-22 22 views
162

तो, मैंने कोड का एक समूह लिखा जो इंडेक्स [] द्वारा एक एसएलएल वेक्टर में तत्वों तक पहुंचता है, लेकिन अब मुझे वेक्टर के केवल एक हिस्से की प्रतिलिपि बनाने की आवश्यकता है। ऐसा लगता है कि vector.insert(pos, first, last) वह फ़ंक्शन है जो मैं चाहता हूं ... सिवाय इसके कि मेरे पास केवल पहले और आखिरी चींटियां हैं। क्या कोई अच्छा तरीका है कि मैं इन मूल्यों के लिए एक इटरेटर प्राप्त कर सकता हूं?सी ++ एसटीएल वेक्टर: सूचकांक से इटरेटर प्राप्त करें?

+1

देखें: http://stackoverflow.com/q/2152986/365102 –

उत्तर

234

इस प्रयास करें:

vector<Type>::iterator nth = v.begin() + index; 
+4

आम तौर पर, आप के साथ की तुलना में एसटीएल iterators के साथ एक ही गणित का उपयोग कर सकते संकेत दिए गए। एसटीएल एल्गोरिदम का उपयोग करते समय उन्हें विनिमय योग्य बनाने के लिए डिज़ाइन किया गया है। –

+14

@VincentRobert: आसपास के अन्य तरीके। पॉइंटर्स एसटीएल यादृच्छिक iterators, सबसे शक्तिशाली श्रेणी के वैध कार्यान्वयन हैं। लेकिन अन्य, कम शक्तिशाली श्रेणियां जैसे अग्रेषित इटरेटर्स समान अंकगणित का समर्थन नहीं करते हैं। – MSalters

+0

मैं चाहता हूं कि मैं अपने पांच सेंट को इस उत्तर में जोड़ूं और अनुशंसा करता हूं कि 'std :: अगला (v.begin(), अनुक्रमणिका) ' – stryku

75

रास्ता @dirkgently (v.begin() + index) अच्छा और के लिए तेजी से वैक्टर

लेकिन std::advance(v.begin(), index) सबसे सामान्य तरीके से और रैंडम एक्सेस iterators के लिए भी लगातार समय काम करता है उल्लेख किया।

संपादित उपयोग में
मतभेद:

std::vector<>::iterator it = (v.begin() + index); 

या

std::vector<>::iterator it = v.begin(); 
std::advance(it, index); 

@litb नोटों के बाद जोड़ा।

+0

std :: अग्रिम को पहले तर्क के रूप में गैर-कॉन्स्ट इटरेटर की आवश्यकता नहीं है? – goldPseudo

+0

इस के अनुसार - http://www.sgi.com/tech/stl/advance.html - नहीं। – bayda

+0

आप std :: अग्रिम का उपयोग कॉन्स और गैर-कॉन्स इटरेटर्स – bayda

-3

सक्रिय रूप से std :: वेक्टर को आवश्यक होने पर सी टैब के रूप में उपयोग करने के लिए उपयोग किया जाता है। (सी ++ मानक अनुरोध करता है कि वेक्टर कार्यान्वयन के लिए, जहाँ तक मुझे पता है - replacement for array in Wikipedia) उदाहरण के लिए यह पूरी तरह इस folowing करने के लिए कानूनी है, मेरे हिसाब से:

int main() 
{ 

void foo(const char *); 

sdt::vector<char> vec; 
vec.push_back('h'); 
vec.push_back('e'); 
vec.push_back('l'); 
vec.push_back('l'); 
vec.push_back('o'); 
vec.push_back('/0'); 

foo(&vec[0]); 
} 
बेशक

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

इसलिए अपने उदाहरण में यह

vector.insert(pos, &vec[first_index], &vec[last_index]); 
+0

मुझे आश्चर्य है कि उन्होंने इटरेटर को दूर करने का फैसला क्यों किया है यदि वे केवल पॉइंटर्स हैं ... वे अनिवार्य रूप से इन क्षमताओं को "छुपा रहे हैं"। – mpen

+0

संवेदना के लिए? चूंकि यह आपको अपने कोड में किसी अन्य प्रकार के कंटेनर के लिए वेक्टर इंस्टेंस को आसानी से हटाने की अनुमति देगा। –

+4

और वीसी [i] एक सूचक उत्पन्न करता है जो वेक्टर <> :: iterator के साथ जरूरी नहीं है। vec.begin() + उदाहरण के लिए, मुझे अभी भी आपकी लाइब्रेरी को परिभाषित करने वाला लाभ होने का लाभ है - डीबग मोड में चेक किए गए इटरेटर्स सहित। इसलिए, यदि आपको पॉइंटर की आवश्यकता नहीं है (उदाहरण के लिए I/O के लिए), तो आपको हमेशा इटरेटर पसंद करना चाहिए। – sellibitze

7

की ओर जाता है या फिर आप std::advance

vector<int>::iterator i = L.begin(); 
advance(i, 2); 
33

भी उपयोग कर सकते हैं; auto it = std::next(v.begin(), index);

अद्यतन: एक सी ++ 11x अनुरूप संकलक की जरूरत भी

+2

यह ध्यान दिया जाना चाहिए कि यह सी ++ 11 रास्ता है! std :: अगला std :: अग्रिम के बराबर है। अंकगणित का उपयोग करने के बजाए इन कार्यों का उपयोग करना कंटेनर प्रकारों को स्वैप करना बहुत आसान बनाता है। सी-एरेज़ afaik पर भी काम करता है, बस std :: start और std :: end की तरह। – Zoomulator

+2

यह भी ध्यान दिया जाना चाहिए कि std :: अग्रिम बेवकूफ द्वारा डिज़ाइन किया गया है क्योंकि यह आउटपुट के रूप में संदर्भ का उपयोग करता है, न कि वापसी मूल्य। –

+1

के लिए (ऑटो इसे = शुरू करें (सी); यह! = अंत (सी); अग्रिम (यह, एन)) {...} – Zoomulator

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