2013-07-05 10 views
9

के लिए एंड्रैटर के सीरेंटिक्स सी ++ मानक के अनुसार, वेक्टर पर push_back() पर कॉल करने से वेक्टर के नए आकार की क्षमता बढ़ जाती है, लेकिन सूची में यह कभी भी इटरेटर्स को अमान्य नहीं करता है। अब विचार करें निम्नलिखित कोड के टुकड़े:वेक्टर और सूची

1.

vector<int> v{1,2,3}; 
v.reserve(100); 
for (int i: v) { 
    v.push_back(i); 
} 

2.

list<int> l{1,2,3}; 
for (int i: l) { 
    l.push_back(i); 
} 

मैं जीसीसी 4.8 के साथ इसे करने की कोशिश और उस कोड पाया v जा रहा है {1,2,3,1,2,3} साथ 1 खत्म, लेकिन कोड 2 रन एक अनंत लूप में। स्पष्टीकरण मेरे लिए बहुत आसान लगता है: end()vector के संकेतक स्मृति स्थान पर इंगित करते हैं, और it is only evaluated once during a range based for loop से, यह तब होता है जब यह वेक्टर के तीसरे तत्व से पहले पहुंच जाता है। दूसरी तरफ, list में शायद किसी प्रकार का नल टोकन एक अंत इटरेटर के रूप में होता है, जिसे हमेशा अंतिम तत्व के बाद रखा जाता है, इस प्रकार लूप कभी नहीं पहुंच पाएगा।

जबकि परिणाम सीधे दिखते हैं, मेरा सवाल यह है कि मानक इस बारे में क्या कहता है? क्या यह हर मानक पुस्तकालय कार्यान्वयन में ऐसा होना चाहिए, या यह व्यवहार परिभाषित नहीं है? ऐसे लूप को लिखते समय मुझे क्या उम्मीद करनी चाहिए जो push_back() को ऐसे कंटेनर पर कॉल कर सकता है (जिसे मैं आमतौर पर किसी भी तरह से बचाना पसंद करता हूं)?

+0

मुझे लगता है कि मानक के बारे में कहने के लिए बहुत कुछ नहीं है। इसकी अनुमति है, यह कानूनी है, यह सिर्फ एक अनंत लूप –

+0

@AndyProwl मुझे लगता है कि मानक के पास कुछ कहना है: यह एक अंतहीन पाश होना आवश्यक है। (यदि यह 'वेक्टर' के साथ एक अंतहीन पाश नहीं है, तो ऐसा इसलिए है क्योंकि अपरिभाषित व्यवहार है, इसलिए कार्यान्वयन कुछ भी कानूनी है।) –

+0

@ जेम्ससांज: ठीक है, यही वही है जो मैं कहना चाहता था। ओपी ने एक कानूनी अनंत लूप लिखा, उस विशेष स्थिति के बारे में मानक कुछ भी कहना नहीं है (पाठ्यक्रम की सूची उदाहरण के बारे में बात करना)। –

उत्तर

5

मुझे नहीं लगता कि कि मानक बहुत स्पष्ट है, लेकिन सामान्य रूप में, endend का मतलब है, और यदि आप एक पाश में परे तत्वों को सम्मिलित वर्तमान स्थिति है, तो आप कभी नहीं वहाँ मिल जाएगा।

बेशक

, vector के साथ अपना पहला पाश,, (और मिटा) व्यवहार अपरिभाषित है, सम्मिलित के बाद से पर या प्रविष्टि की स्थिति से बाहर सभी iterators को अमान्य कर, वहाँ है भले ही कोई पुनः आबंटन। और अंत इटरेटर हमेशा प्रविष्टि के बिंदु से आगे होगा।

+0

cppreference.com के अनुसार, 'वेक्टर' में इटरेटर केवल तभी अमान्य होते हैं जब आकार क्षमता के माध्यम से बढ़ता है। http://en.cppreference.com/w/cpp/container/vector/push_back क्या यह मानक को सही ढंग से प्रतिबिंबित करता है, या क्या यह कहता है कि उन्हें किसी भी कॉल पर 'push_back' पर अमान्य किया जा सकता है? – petersohn

+0

@petersohn: cppreference सचमुच कहता है "... अन्यथा कोई इटरेटर और संदर्भ अमान्य नहीं हैं।" यह पेटेंट गलत है। पूरी तरह से "भौतिक" दृष्टिकोण से कोई भी अपने तर्क को समझ सकता है, लेकिन भाषा का नमूना अधिक उच्च स्तरीय दृष्टिकोण लेता है। सभी इटरेटर्स और संदर्भ जो "स्थानांतरित" तत्वों को संदर्भित करते हैं उन्हें अमान्य माना जाता है, भले ही वे अभी भी वैध स्मृति स्थानों का संदर्भ ले सकें। – AnT

+1

@petersohn मानक के अनुसार (§23.3.6.5): "[...] यदि पुनर्वितरण होता है, तो से पहले सभी पुनरावृत्तियों और संदर्भ सम्मिलन बिंदु मान्य रहते हैं। "(यदि वे वैध रहने के लिए की गारंटी नहीं देते हैं, तो वे अमान्य हैं। यह साइट पर उद्धृत साइट पर एक स्पष्ट त्रुटि है। –

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