कंपाइलर पहले में दूसरे को अनुकूलित करने में सक्षम हो सकता है, लेकिन यह मानता है कि दोनों बराबर हैं, यानी अंत() वास्तव में स्थिर है। थोड़ा और समस्याग्रस्त मुद्दा यह है कि संकलक यह साबित करने में असमर्थ हो सकता है कि अंतिम एलियासिंग के कारण एंडरेटर स्थिर है। हालांकि, यह मानते हुए कि कॉल() को अंत में निर्दिष्ट किया गया है, अंतर केवल एक स्मृति लोड है।
ध्यान दें कि यह मानता है कि अनुकूलक सक्षम है। यदि ऑप्टिमाइज़र सक्षम नहीं है, जैसा अक्सर डीबग बिल्ड में किया जाता है, तो दूसरे फॉर्मूलेशन में एन -1 और अधिक फ़ंक्शन कॉल शामिल होंगे। विजुअल सी ++ के मौजूदा संस्करणों में, डीबग बिल्ड्स में फ़ंक्शन प्रोलॉग/एपिलॉग चेक और भारी डीबग इटरेटर्स के कारण अतिरिक्त हिट भी होंगे। इसलिए, एसटीएल भारी कोड में, पहले मामले में डिफॉल्ट करने से डीबग बिल्ड में कोड को असमान रूप से धीमा होने से रोक सकता है।
लूप के भीतर सम्मिलन और निष्कासन एक संभावना है, जैसा कि अन्य ने इंगित किया है, लेकिन लूप की इस शैली के साथ मुझे यह असंभव लगता है। एक बात के लिए, नोड-आधारित कंटेनर - सूची, सेट, मानचित्र - किसी भी ऑपरेशन पर अंत() को अमान्य नहीं करें। दूसरा, इटरेटर वेतन वृद्धि अक्सर अमान्यकरण समस्याओं से बचने के लिए लूप स्थानांतरित करने की है:
// assuming list -- cannot cache end() for vector
iterator it(c.begin()), end(c.end());
while(it != end) {
if (should_remove(*it))
it = c.erase(it);
else
++it;
}
इस प्रकार, मैं एक पाश में बदलें-दौरान लूप कारणों के लिए अंत() कॉल करने के लिए दावा करता है और अभी भी है कि पर विचार ++ यह लूप हेडर में संदिग्ध होने के लिए।
स्रोत
2009-04-28 22:30:50
'ite' के लिए घोषणा एक वाक्यविन्यास त्रुटि होगी, इसलिए आपका पहला संस्करण "(const_iterator i = list.begin(), e = list.end(); i! = E; ++ i)" के लिए बन जाता है। यह दूसरे रूप की तुलना में केवल कुछ और वर्ण हैं, इसलिए मैं इसे डिफ़ॉल्ट रूप से उपयोग करता हूं। – Bklyn
अब सी ++ 11 में 'इसके लिए (ऑटो इसे: सूची)' भी है जो अनिवार्य रूप से दूसरा है। लेकिन बहुत अच्छा है। – Cramer
@ क्रैमर रेंज-तत्वों पर लूप के लिए आधारित है, इटेटरेटर पदों पर नहीं, इसलिए समकक्ष '(कॉन्स ऑटो और एलिमेंट: सूची) ' – boycy