2009-11-03 32 views
10

मैं अपने आप को निम्नलिखित एक बहुत लिख पाया:std :: vector std :: अग्रिम वीएस ऑपरेटर + के लिए एडवांस इटरेटर?

it= it + 5; 

की

int location =2; 
vector<int> vec; 
vector<int>::iterator it=vec.begin(); 

/..../ 
std::advance(it, location); 

बजाय क्या पसंदीदा/अनुशंसित तरीका है?

उत्तर

16

जोड़ना केवल यादृच्छिक अभिगम इटरेटर के साथ काम करेगा। std :: अग्रिम iterators के सभी प्रकार के साथ काम करेगा। जब तक आप केवल वैक्टर में हीटरेटर से निपट रहे हों, इससे कोई वास्तविक अंतर नहीं होता है, लेकिन std :: अग्रिम आपके कोड को अधिक सामान्य रखता है (उदाहरण के लिए आप वेक्टर के लिए एक सूची को प्रतिस्थापित कर सकते हैं, और वह हिस्सा अभी भी काम करेगा)।

संपादित करें: जो लोग परवाह के लिए, मानक advance और distance का वर्णन इस प्रकार (§24.3.4/1):

के बाद से केवल रैंडम एक्सेस iterators + और प्रदान करते हैं - ऑपरेटरों, पुस्तकालय दो समारोह प्रदान करता है टेम्पलेट advance और distance। इन फ़ंक्शन टेम्पलेट्स + और - का उपयोग यादृच्छिक एक्सेस इटरेटर्स (और इसलिए, उनके लिए निरंतर समय) के लिए करते हैं; इनपुट, फॉरवर्ड और बिडरेक्शनल इटरेटर्स के लिए वे रैखिक समय कार्यान्वयन प्रदान करने के लिए ++ का उपयोग करते हैं।

+12

दूसरी तरफ, कम जेनेरिक कोड का उपयोग करके आपको अनजाने में कोड को धुंधला करने से रोक दिया जाएगा: आखिरकार एक सूची कंटेनर के साथ "यादृच्छिक पहुंच" करने के लिए बहुत अच्छा विचार नहीं हो सकता है। – UncleBens

0

यह पुनरावर्तक पर निर्भर करता है। it=it+5 तेज है अगर यह समर्थित है (यह केवल यादृच्छिक अभिगम iterators पर समर्थित है)। यदि आप एक कम सक्षम इटरेटर (जैसे एक फॉरवर्ड इटरेटर, या बिडरेक्शनल इटरेटर) अग्रिम करना चाहते हैं, तो आप std::advance का उपयोग कर सकते हैं, लेकिन यह धीमा है क्योंकि यह वास्तव में सभी मध्यवर्ती तत्वों में चलता है।

+1

आप गलत हैं कि मानक निर्देश है कि std :: अग्रिम यादृच्छिक अभिगम अनुक्रमों के लिए रैखिक है: "जटिलता: निरंतर समय अगर इनपुटइटरेटर यादृच्छिक अभिगम इटरेटर का मॉडल है, अन्यथा रैखिक समय।" – Blindy

+1

std :: अग्रिम यादृच्छिक अभिगम iterators (§24.3.4/1) के लिए निरंतर समय है। –

+0

मुझे नहीं लगता कि यह यादृच्छिक अभिगम iterators के लिए सच है - std :: अग्रिम उस मामले में + ऑपरेटर के रूप में उतना ही कुशल होना चाहिए। – Kylotan

0

std::advance गैर-यादृच्छिक पुनरावृत्तियों पर भी काम करता है जबकि += संस्करण यादृच्छिक अभिगम अनुक्रमों (वैक्टर और इसी तरह) पर काम करता है।

0

std::adnvance सामान्य है - यदि आप हमेशा अंतर्निहित कंटेनर के प्रकार को नहीं जानते हैं तो यह उपयोगी होता है - यह सभी मामलों में काम करता है।

अभी तक यह कुशल है: std::advance अगर यह एक RandomAccessIterator पारित कर दिया (std::vector से एक की तरह) एक अनुकूलन करना होगा और ForwardAccessIterator के लिए पाश में इटरेटर में वृद्धि होगी (के रूप में std::list में से एक की तरह)।

0

std :: अग्रिम का उपयोग करें। यह उतना ही कुशल है (यह केवल यादृच्छिक अभिगम इटरेटर के लिए इटेटरेटर अतिरिक्त करने के लिए इटेटरेटर लक्षणों का उपयोग करता है), और यह सामान्य है कि यह अन्य प्रकार के इटरेटर पर भी काम करता है।

7

कि आपको क्या चाहिए पर निर्भर करता है:

आप की जरूरत है genericity, std::advance(it,2) का उपयोग करें। यदि कोई व्यक्ति std::vector को std::list में बदलता है और बदलता है, तो कोड अभी भी संकलित होगा, भले ही आगे बढ़ने के बजाय आगे बढ़ने वाला समय लगे।

आप प्रदर्शन की जरूरत है, it+=2 का उपयोग करें। यदि कोई व्यक्ति std::vector को std::list में बदलता है और बदलता है, तो कोड एक गंभीर प्रदर्शन समस्या पर इंगित करने में विफल हो जाएगा (शायद एक सहायक टिप्पणी के साथ)।

0

यदि आप कंटेनर को बदलने के लिए कभी भी नहीं जा रहे हैं (और आप शायद नहीं हैं), तो + का उपयोग करें क्योंकि यह देखने और समझने में आसान है और कोड को कम अव्यवस्थित छोड़ देता है।

यदि आपको लगता है कि आप कंटेनर को बदलना चाहते हैं, या यदि आप एक टेम्पलेट के अंदर काम कर रहे हैं जो विभिन्न कंटेनर प्रकारों पर तत्काल हो सकता है, तो अग्रिम का उपयोग करें क्योंकि यह किसी भी चीज़ के साथ काम करता है।

एक सामान्य नियम के रूप में, मुझे कंटेनर प्रकार बदलने के बारे में चिंता नहीं है क्योंकि मुझे पता चला है कि जब मुझे एक कंटेनर प्रकार बदलना होता है, तो मैं हर जगह फिर से जाना चाहता हूं कि कंटेनर का उपयोग वैसे भी किया जाता है, बस यह सुनिश्चित करने के लिए कि मैं मैं कुछ भी नहीं कर रहा हूं जो अचानक बेवकूफ है (जैसे किसी सूची के बीच से यादृच्छिक रूप से तत्वों को खींचना)।

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