2010-05-13 5 views
9

मुझे एसटीएल list इटेटरेटर के लिए अब तक का अगला मूल्य मिलना है, लेकिन यह operator+, vector को लागू नहीं करता है। मुझे वह मूल्य क्यों और कैसे मिल सकता है जहां मैं चाहता हूं?क्यों केवल यादृच्छिक-पहुंच-इटरेटर ऑपरेटर + C++ में लागू करता है?

मुझे लगता है कि मैं ऐसा कर सकता हूं अगर मैं operator++ कई बार कॉल करता हूं, लेकिन क्या यह थोड़ा गंदा नहीं है?

list<int> l; 
...omitted... 
list<int>::iterator itr = l.begin() + 3; // but, list iterator does not have 
             // operator+ 

मैं क्या चाहते हैं के लिए सबसे अच्छा समाधान क्या है:

मुझे क्या करना चाहते हैं निम्नलिखित है? जबकि यह रेखीय समय में operator++ पर पाश और पूर्ण करता है, तो इटरेटर नहीं रैंडम एक्सेस है जाएगा अगर इटरेटर रैंडम एक्सेस है

list<int>::iterator itr = l.begin(); 
std::advance(itr, 3); 

advance निरंतर समय में operator+ और पूरा उपयोग करेगा:

+2

(लगभग) असंबंधित: आपको यह सुनिश्चित करने की आवश्यकता है कि इस स्थिति तक पहुंचना संभव है, अन्यथा आप अपरिभाषित व्यवहार का आह्वान करेंगे। हालांकि 'सूची :: से शुरू करें() 'अधिक सामान्य मामले में, यह आसान है (गैर रैंडमएक्सइटरेटर के लिए)' सूची :: अंत()' के साथ दूरी 'std :: दूरी '... ओ (एन) भी। –

+0

इस धागे पर दो उत्कृष्ट जवाब। समुदाय को +1! –

उत्तर

17

यदि आप सी ++ 11 तक पहुंच नहीं रखते हैं तो आप std::next (और पिछला) या बूस्ट द्वारा प्रदान किए गए समकक्षों का भी उपयोग कर सकते हैं।

list<int>::iterator itr = std::next(l.begin(), 3); 

दलील: std::advance (यह पक्ष प्रभाव से काम करता है, एक प्रति वापस लौट कर नहीं) का उपयोग करने के लिए अजीब है।

+2

यह जानना अच्छा है। मैंने हमेशा सोचा कि क्यों 'std :: advance' ने कार्यात्मक रूप से साइड-इफेक्ट द्वारा काम किया। –

+1

@RSam: मैंने हमेशा यह माना है कि ऐसा इसलिए है क्योंकि 'std :: advance' का अर्थ ++ itr या ऑपरेटर + = की नकल करने के लिए है। इटरेटर एल्गोरिदम आमतौर पर उन शर्तों में लिखे जाते हैं, इसलिए उन्हें लपेटना सबसे अधिक समझ में आता है। –

+0

यदि आप एक प्रतिलिपि चाहते हैं तो आपको खुद को बनाना होगा। सी ++ में यह सामान्य मामला है। – mschneider

37

आप का उपयोग करने के std::advance चाहते ।  

इसका कारण आपको जटिलता आवश्यकताओं पर नियंत्रण देना है। यदि आप अपने ऑपरेशन की जटिलता की परवाह करते हैं तो आप operator+ का उपयोग करते हैं और निरंतर समय प्राप्त करते हैं लेकिन यह केवल यादृच्छिक एक्सेस इटेटर के साथ संकलित करता है। यदि आपको जटिलता की परवाह नहीं है तो आप std::advance का उपयोग करते हैं जो हमेशा काम करेगा लेकिन जटिलता इटरेटर के आधार पर अलग-अलग होगी।

+3

+1 सरल, स्पष्ट और पूरी तरह से +1। – wilhelmtell

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