2013-02-27 224 views
5

मैं लिख रहा हूँ एक iterator (वास्तव में यह मेरे वर्तमान वस्तु के लिए const_iterator है, और मैं एक reverse_const_iterator भी बनाने के लिए भी चाहते हैं।सी ++ इटरेटर और रिवर्स इटरेटर

मैं चारों ओर देखा, ऐसा करने के तरीके को देखने के लिए और मैं this भर में ठोकर खाई:।

सूचना तथापि है कि जब एक इटरेटर उलट है, उलट संस्करण रेंज में एक ही तत्व को इंगित नहीं करता है, लेकिन एक करने के लिए इसे पूर्ववर्ती यह इसलिए है, आदेश की व्यवस्था करने में अतीत के अंत एक सीमा के तत्व के लिए: यह एक में एक अतीत-अंत-अंत तत्व को इंगित करने वाला इरेटर, रेंज के बाद, अंतिम तत्व ( पिछला) पर इंगित करने के लिए बदल दिया गया है ( उलट होने पर यह श्रेणी का पहला तत्व होगा)। और यदि किसी श्रेणी में पहले तत्व के लिए एक पुनरावर्तक उलट है, तो उल्टा इटरेटर पहले तत्व से पहले तत्व को इंगित करता है ( उलट होने पर यह सीमा का अतीत-अंत तत्व होगा)।

यह है कि क्या उपयोगकर्ताओं के नजरिए से होता है, या जब आप एक reverse_iterator भिन्नता यह नहीं है यह दूर सार आप वस्तु आपको लगता है यह की ओर इशारा करते है मूल्य/संदर्भ देकर? क्या यह सिर्फ कार्यान्वयन विस्तार है?

मेरे समझ गया था:

for(i = obj.rbegin(); i != obj.rend(); i++) 

for(i = obj.begin(); i != obj.end(); i++) 

के बराबर था रिवर्स में छोड़कर। और इसलिए *i पहले मामले में कंटेनर के माध्यम से पिछड़ा होगा, और दूसरे मामले में कंटेनर के माध्यम से आगे बढ़ेगा। क्या मेरा वृत्ति सही है?

+2

यह सिर्फ काम करता है। –

+0

एक साइड नोट के रूप में: इटरेटर्स के साथ काम करते समय आपको हमेशा वृद्धि के बजाय पूर्व-वृद्धि ('++ i') का उपयोग करना चाहिए क्योंकि यह अधिक कुशल हो सकता है। –

उत्तर

5

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

मानक इटरेटर के लिए निम्न संबंध वाले पुनरावर्तक एडाप्टर के रूप में परिभाषित करता है std::reverse_iterator इसकी आदत डाल:

मैं पहचान द्वारा स्थापित है एक रिवर्स इटरेटर और उसके संगत iterator के बीच मौलिक संबंध: &*(reverse_iterator(i)) == &*(i - 1)

it++; 
lst.erase(it.base()); 
:

base का उपयोग आम एक कंटेनर है, जो इतनी तरह किया जाएगा, जो कि एक तत्व को मिटा रहा है

आप इस जबकि रिवर्स में कंटेनर से अधिक पुनरावृत्ति करना चाहते हैं, तो आप करना होगा:

it++; 
std::list<int>::reverse_iterator(lst.erase(it.base())); 
+0

एक साइड सवाल के रूप में, 'आधार' अंतर्निहित 'iterator' प्राप्त करने के लिए कभी भी उपयोगी क्यों होगा? – Bingo

+0

@ बिंगो: क्योंकि कंटेनर इसकी अपेक्षा कर सकते हैं, उदाहरण के लिए, 'मिटाएं' को 'इटरेटर' और * नहीं * एक 'रिवर्स_इटरेटर' लेने के रूप में निर्दिष्ट किया गया है। –

+0

@Maththieu ओह, ठीक है। यह समझ आता है। – Bingo