दिलचस्प पोस्ट
जांचें कि क्या http अनुरोध मेरे एंड्रॉइड ऐप से आता है रैगेक्स के साथ एक स्ट्रिंग में कोई संख्या बढ़ाएं जावा / कन्वर्ट ISO-8601 (2010-12-16T13: 33: 50.513852Z) तिथि वस्तु के लिए जावास्क्रिप्ट पर गंतव्य यूआरएल कैसे प्राप्त कर सकता है? अपवादित वर्ग स्थिर 'MYSQL_ATTR_INIT_COMMAND' पीडो के साथ Json स्ट्रिंग को जावा ऑब्जेक्ट में परिवर्तित करना? रेज़र: घोषणात्मक HTML सहायकों हमेशा एआरसी में ब्लॉक में आत्म का कमजोर संदर्भ पास करें? सीटीआईपीज़ के साथ एक साझा लाइब्रेरी से वैश्विक वैरिएबल मैप करना कैसे एक बैच फ़ाइल के साथ FTP? ऑटोमैपर – कैसे संपत्ति सेटर्स के बजाय कन्स्ट्रेटर मापदंडों को मैप करने के लिए पर्ल की बैकल्टी, सिस्टम और एप के बीच क्या अंतर है? स्थितिबद्ध लापता है, लेकिन यह वहां है जावा-स्क्रिप्ट में एन-आकार के विभाजनों में बड़ी स्ट्रिंग विभाजित करें रत्न (खिड़कियां) पर मणि स्थापित करें। libv8 –version '3.11.8.17'

सरणी सूचकांक के बजाय इटरेटर का उपयोग क्यों करें?

निम्न दो लाइन कोड लें:

for (int i = 0; i < some_vector.size(); i++) { //do stuff } 

और इस:

 for (some_iterator = some_vector.begin(); some_iterator != some_vector.end(); some_iterator++) { //do stuff } 

मुझे बताया गया है कि दूसरा तरीका पसंदीदा है यह वास्तव में क्यों है?

Solutions Collecting From Web of "सरणी सूचकांक के बजाय इटरेटर का उपयोग क्यों करें?"

पहला प्रपत्र केवल तभी प्रभावी होता है जब vector.size () एक तेज़ ऑपरेशन हो। यह वैक्टर के लिए सच है, लेकिन सूचियों के लिए नहीं, उदाहरण के लिए। इसके अलावा, आप लूप के शरीर के भीतर क्या करने की योजना बना रहे हैं? यदि आप में तत्वों तक पहुंचने की योजना है

 T elem = some_vector[i]; 

तो आप धारणा बना रहे हैं कि कंटेनर में operator[](std::size_t) परिभाषित किया गया है। फिर, यह सदिश के लिए सच है लेकिन अन्य कंटेनरों के लिए नहीं है

इटेरेटर्स का इस्तेमाल आपको कंटेनर की स्वतंत्रता के करीब ले जाता है। आप रैंडम-एक्सेस की क्षमता या तेज size() ऑपरेशन के बारे में अनुमान नहीं बना रहे हैं, केवल कंटेनर में इटरेटर क्षमताएं हैं

आप मानक एल्गोरिदम का उपयोग करके आगे अपना कोड बढ़ा सकते हैं। आप क्या हासिल करने की कोशिश कर रहे हैं इसके आधार पर, आप std::for_each() , std::transform() और इसी तरह का उपयोग कर सकते हैं। एक स्पष्ट लूप के बजाय एक मानक एल्गोरिदम का उपयोग करके आप पहिया का पुनः-खोज करने से बच रहे हैं। आपका कोड अधिक कुशल होने की संभावना है (सही एल्गोरिथ्म चुना गया है), सही और पुन: प्रयोज्य।

क्योंकि आप some_vector सूची के विशेष कार्यान्वयन के लिए अपना कोड टाइप नहीं कर रहे हैं यदि आप सरणी सूचकांक का उपयोग करते हैं, तो उसे कुछ सरणी का होना चाहिए; यदि आप इटेरेटर का उपयोग करते हैं तो आप उस कोड को किसी भी सूची कार्यान्वयन पर उपयोग कर सकते हैं।

यह आधुनिक सी ++ अभिसरण प्रक्रिया का हिस्सा है सबसे अधिक कंटेनरों को पुनरावृत्त करने का एकमात्र तरीका है, इसलिए आप अपने आप को उचित मानसिकता में लाने के लिए वैक्टर के साथ भी इसका इस्तेमाल करते हैं। गंभीरता से, यह एकमात्र कारण है कि मैं करता हूं – मुझे नहीं लगता कि मैंने कभी एक अलग प्रकार के कंटेनर के साथ एक वेक्टर की जगह ली है।


वाह, यह अभी भी तीन सप्ताह के बाद डाउनवॉट हो रही है मुझे लगता है कि यह थोड़ा जीभ-इन-गाल होने का भुगतान नहीं करता है

मुझे लगता है कि सरणी सूचकांक अधिक पठनीय है। यह अन्य भाषाओं में इस्तेमाल किया वाक्यविन्यास से मेल खाता है, और पुराने फ़ैशन वाले सी एरेज़ के लिए उपयोग किए गए सिंटैक्स। यह भी कम वर्बोस है यदि आपके कंपाइलर किसी भी अच्छा है, तो दक्षता एक धोना होनी चाहिए, और शायद ही किसी भी मामले हैं जहां यह वैसे भी मायने रखता है।

फिर भी, मैं अभी भी वेटर्स के साथ बार-बार फिर से अपने आप को ढूंढता हूं। मेरा मानना ​​है कि इटरेटर एक महत्वपूर्ण अवधारणा है, इसलिए जब भी मैं कर सकता हूं, उसे बढ़ावा देता हूं।

कल्पना कीजिए some_vector एक लिंक-सूची के साथ कार्यान्वित किया गया है। फिर आई-वें स्थान में एक आइटम का अनुरोध करने की आवश्यकता है कि नोड्स की सूची को पार करने के लिए ऑपरेशन किया जाए। अब, यदि आप इटरेटर का प्रयोग करते हैं, आम तौर पर बोलते हैं, तो यह संभव के रूप में कुशल होने का अपना सर्वश्रेष्ठ प्रयास करेगा (एक लिंक्ड सूची के मामले में, यह वर्तमान नोड के लिए एक संकेतक बनाएगा और इसे प्रत्येक आवृत्ति में अग्रेषित करेगा, केवल एक एकल ऑपरेशन)।

तो यह दो चीजें प्रदान करता है:

  • उपयोग के अमूर्त: आप बस कुछ तत्वों को पुनरावृति करना चाहते हैं, आपको इसकी परवाह नहीं है कि यह कैसे करना है
  • प्रदर्शन

मैं शैतानों के यहां अधिवक्ता होने जा रहा हूं, और इटेरेटर की सिफारिश नहीं करता हूं। मुख्य कारण यह है कि, डेस्कटॉप अनुप्रयोग विकास से खेल विकास के लिए मैंने जो स्रोत स्रोत काम किया है वह है I और इसके लिए मुझे इटेटर का उपयोग करने की आवश्यकता नहीं है I हर समय उन्हें जरूरी नहीं है और दूसरी बात यह है कि छुपा धारणाएं और कोड गड़बड़ और डिबगिंग बुरे सपने जिसे आप इटेटर के साथ मिलते हैं, उन्हें किसी भी ऐसे एप्लिकेशन में उपयोग नहीं करने के लिए एक आदर्श उदाहरण बनाते हैं जो गति की आवश्यकता होती है

यहां तक ​​कि एक रखरखाव स्टैंड बिंदु से भी वे एक गड़बड़ कर रहे हैं इसका कारण यह नहीं है, लेकिन इस दृश्य के पीछे होने वाले सभी एलियासिंग के कारण मुझे कैसे पता है कि आपने अपना वर्चुअल वेक्टर या ऐरे सूची कार्यान्वित नहीं की है जो मानकों से पूरी तरह से भिन्न है क्या मुझे पता है कि वर्तमान में रनटाइम के दौरान क्या प्रकार है? क्या आप ऑपरेटर को अधिभार देते थे, मेरे पास अपने सभी स्रोत कोड की जांच करने के लिए समय नहीं था नरक क्या मुझे भी पता है कि आपके प्रयोग के एसटीएल का क्या संस्करण है?

अगली समस्या, जिसे आप iterators के साथ मिलती है, रिक्ति का अमूर्त है, हालांकि इसमें कई वेब साइट हैं जो उनके साथ विस्तार से इस पर चर्चा करते हैं।

क्षमा करें, मेरे पास नहीं है और फिर भी iterators में कोई बिंदु नहीं देखा है। यदि वे सूची या वेक्टर को आप से दूर करते हैं, तो वास्तव में आपको पहले से ही पता होना चाहिए कि वेक्टर क्या है या यदि आप ऐसा नहीं करते हैं, तो आप भविष्य में कुछ महान डिबगिंग सत्रों के लिए अपने आप को स्थापित करने जा रहे हैं।

यदि आप वेक्टर पर वस्तुओं को जोड़ने / निकालने जा रहे हैं, तो आप इटरेटर का उपयोग करना चाहेंगे।

 some_iterator = some_vector.begin(); while (some_iterator != some_vector.end()) { if (/* some condition */) { some_iterator = some_vector.erase(some_iterator); // some_iterator now positioned at the element after the deleted element } else { if (/* some other condition */) { some_iterator = some_vector.insert(some_iterator, some_new_value); // some_iterator now positioned at new element } ++some_iterator; } } 

यदि आप इंडेक्स का इस्तेमाल कर रहे थे तो आपको सम्मिलन और हटाना को संभालने के लिए सरणी में वस्तुओं को ऊपर / नीचे फेंकना होगा।

चिंताओ का विभाजन

यह लूप के 'कोर' चिंता से चलना कोड को अलग करने के लिए बहुत अच्छा है यह लगभग एक डिजाइन निर्णय है

दरअसल, सूचकांक से दोबारा आप कंटेनर के कार्यान्वयन के संबंध में संबंध हैं कंटेनर को एक आरंभ और अंत इटरेटर के लिए पूछते हुए, अन्य कंटेनर प्रकारों के उपयोग के लिए लूप कोड को सक्षम करता है।

इसके अलावा, std::for_each , आप अपने आंतरिक के बारे में कुछ पूछने के बजाय संग्रह को बताते हैं

0x मानक बंद करने की शुरुआत कर रहा है, जिससे इस दृष्टिकोण का उपयोग करना अधिक आसान होगा – उदाहरण के लिए रूबी की [1..6].each { |i| print i; } अभिव्यक्ति शक्ति पर एक नजर डालें [1..6].each { |i| print i; } [1..6].each { |i| print i; } [1..6].each { |i| print i; }

प्रदर्शन

लेकिन हो सकता है कि एक बहुत अधिक निगमित मुद्दे यह है कि, for_each दृष्टिकोण का उपयोग करके चलने के समानांतर के अवसर पैदा होते हैं- इंटेल थ्रेडिंग ब्लॉक प्रणाली में प्रोसेसर की संख्या पर कोड ब्लॉक वितरित कर सकते हैं!

नोट: algorithms पुस्तकालय की खोज करने के बाद, और विशेष रूप से foreach , मैं दो या तीन महीनों से हास्यास्पद छोटे 'सहायक' ऑपरेटर structs लिख रहा था जो आपके साथी डेवलपर्स को पागल बना देगा इस समय के बाद, मैं व्यावहारिक दृष्टिकोण पर वापस चला गया – छोटे पाश निकायों को कोई और नहीं foreach लायक 🙂

ए को पढ़ने वालों को संदर्भ पढ़ना चाहिए "विस्तारित एसटीएल" है

गोएफ़ के पास इटरेटर पैटर्न के अंत में एक छोटा सा अनुच्छेद होता है, जो इस ब्रांड के पुनरावृत्ति के बारे में बात करता है; इसे 'आंतरिक इटरेटर' कहा जाता है यहाँ एक नज़र भी है , बहुत

क्योंकि यह अधिक वस्तु-उन्मुख है। यदि आप एक सूचकांक के साथ फिर से चल रहे हैं जो आप सोच रहे हैं:

क) उन वस्तुओं का आदेश दिया जाता है
बी) कि उन वस्तुओं को एक सूचकांक से प्राप्त किया जा सकता है
ग) यह है कि सूचकांक की वृद्धि प्रत्येक आइटम को हिट जाएगी
घ) यह सूचकांक शून्य से शुरू होता है

एक प्रेरक के साथ, आप कह रहे हैं कि "मुझे सब कुछ दे दो ताकि मैं इसके साथ काम कर सकूं" अंतर्निहित कार्यान्वयन क्या है इसके बिना। (जावा में, ऐसे संग्रह हैं जो किसी सूचकांक के माध्यम से एक्सेस नहीं किए जा सकते हैं)

इसके अलावा, एक इटरेटर के साथ, सरणी की सीमा से बाहर जाने के बारे में चिंता करने की कोई जरूरत नहीं है।

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

 for(std::vector<Foo>::const_iterator pos=foos.begin(); pos != foos.end(); ++pos) { // Foo & foo = *pos; // this won't compile const Foo & foo = *pos; // this will compile } 

अन्य सभी उत्कृष्ट उत्तरों के अलावा … int आपके वेक्टर के लिए पर्याप्त नहीं हो सकता है। इसके बजाय, यदि आप अनुक्रमणिका का उपयोग करना चाहते हैं, तो अपने कंटेनर के लिए size_type उपयोग करें:

 for (std::vector<Foo>::size_type i = 0; i < myvector.size(); ++i) { Foo& this_foo = myvector[i]; // Do stuff with this_foo } 

मुझे शायद यह कहना चाहिए कि आप भी कॉल कर सकते हैं

std::for_each(some_vector.begin(), some_vector.end(), &do_stuff);

एसटीएल इटरेटर ज्यादातर वहां होते हैं ताकि एसटीएल एल्गोरिदम सॉर्ट जैसी कंटेनर स्वतंत्र हो सकते हैं।

यदि आप सदिश में सभी प्रविष्टियों पर सिर्फ लूप चाहते हैं तो बस इंडेक्स लूप शैली का उपयोग करें

अधिकांश मनुष्यों के लिए यह कम टाइपिंग और आसान है यह अच्छा होगा अगर सी ++ के पास सामान्य जादूगर के साथ झुकाव किए बिना एक सरल foreach पाश था।

 for( size_t i = 0; i < some_vector.size(); ++i ) { T& rT = some_vector[i]; // now do something with rT } ' 

मुझे नहीं लगता कि यह एक सदिश के लिए बहुत अंतर बनाता है मैं खुद को इंडेक्स का उपयोग करना पसंद करता हूं क्योंकि मैं इसे अधिक पठनीय मानता हूं और आप 6 वस्तुओं को आगे बढ़ाने या जरूरत पड़ने पर पीछे कूदते जैसे यादृच्छिक पहुंच कर सकते हैं।

मैं भी इस तरह के लूप के भीतर आइटम का संदर्भ बनाना चाहूंगा, इसलिए जगह के चारों ओर बहुत सी वर्ग कोष्ठक नहीं हैं:

 for(size_t i = 0; i < myvector.size(); i++) { MyClass &item = myvector[i]; // Do stuff to "item". } 

इटरेटर का उपयोग करना अच्छा हो सकता है यदि आपको लगता है कि आपको भविष्य में किसी बिंदु पर वेक्टर को सूची में बदलना पड़ सकता है और यह भी एसटीएल शैतानों के लिए स्टाइलिश दिखता है, लेकिन मैं किसी अन्य कारण के बारे में नहीं सोच सकता।

दूसरा रूप वह दर्शाता है कि आप और अधिक सटीक क्या कर रहे हैं। आपके उदाहरण में, आप मुझे के मूल्य के बारे में परवाह नहीं करते, वास्तव में – आप जो चाहते हैं वह इटरेटर में अगले तत्व है।

इस उत्तर के विषय पर थोड़ी अधिक जानकारी प्राप्त करने के बाद, मुझे पता है कि यह एक बड़ा आकार था। इस लूप के बीच का अंतर:

 for (some_iterator = some_vector.begin(); some_iterator != some_vector.end(); some_iterator++) { //do stuff } 

और यह लूप:

 for (int i = 0; i < some_vector.size(); i++) { //do stuff } 

काफी कम है वास्तव में, छोर करने की सिंटैक्स इस तरह से मेरे ऊपर बढ़ती जा रही है:

 while (it != end){ //do stuff ++it; } 

Iterators कुछ काफी शक्तिशाली घोषणात्मक विशेषताएं अनलॉक करते हैं, और जब एसटीएल एल्गोरिदम पुस्तकालय के साथ मिलकर आप कुछ बहुत अच्छी चीजें जो सरणी अनुक्रमणिका प्रशासक के दायरे के बाहर कर सकते हैं।

इंडेक्सिंग को एक अतिरिक्त मौल ऑपरेशन की आवश्यकता है। उदाहरण के लिए, वेक्टर वी के लिए, कंपाइलर वी [i] में बदलता है और v + sizeof (int) * i।

पुनरावृत्ति के दौरान आपको संसाधित करने के लिए आइटम की संख्या जानने की आवश्यकता नहीं है। आपको बस आइटम की जरूरत है और इटरेटर्स ऐसे चीजों को बहुत अच्छा कर रहे हैं

कई अच्छे अंक पहले से ही। मेरे पास कुछ अतिरिक्त टिप्पणियां हैं:

  1. यह मानते हुए कि हम सी ++ मानक पुस्तकालय के बारे में बात कर रहे हैं, "वेक्टर" एक यादृच्छिक एक्सेस कंटेनर का अर्थ है जिसमें सी-अर्रे की गारंटी है (यादृच्छिक अभिगम, स्मृति लेआउट आदि)। यदि आपने 'कुछ_कंटेनर' कहा था, तो ऊपर दिए गए बहुत से उत्तर अधिक सटीक होंगे (कंटेनर आजादी आदि)।

  2. संकलक ऑप्टिमाइज़ेशन पर निर्भरता को खत्म करने के लिए, आप some_vector.size () को अनुक्रमित कोड में लूप से बाहर कर सकते हैं, जैसे:

      const size_t numElems = some_vector.size ();
     के लिए (आकार_टी i = 0; i 
  3. हमेशा पूर्व वृद्धि वेतनवाचक और असाधारण मामलों के रूप में वेतनमान के बाद का इलाज।

(some_iterator = some_vector.begin (); some_iterator! = some_vector.end (); ++ some_iterator के लिए) {// do stuff}

तो संभालने और सूचकयोग्य std::vector<> कंटेनर की तरह, कंटेनर के माध्यम से जाने के क्रम में, एक दूसरे को पसंद करने के लिए कोई अच्छा कारण नहीं है यदि आपको पुराने या नए ग्यारह अनुक्रमित अक्सर संदर्भित करना है, तो अनुक्रमित संस्करण अधिक अनुचित है।

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

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

 for(int i=0;i<anims.size();i++) for(int j=0;j<bones.size();j++) { int animIndex = i; int boneIndex = j; // in relatively short code I use indices i and j ... animation_matrices[i][j] ... // in long and complicated code I use indices animIndex and boneIndex ... animation_matrices[animIndex][boneIndex] ... } 

मैं उदाहरण के लिए कुछ यादृच्छिक "anim_matrix" -name-iterator को "एनिमेशन_matrices [i]" जैसी चीज़ों को संक्षिप्त रूप में भी नहीं करना चाहता, क्योंकि तब आप स्पष्ट रूप से नहीं देख सकते हैं कि यह मान किस ओर से उत्पन्न हुआ है।

"सीपीयू को क्या करना है" बताकर भी बेहतर (अनिवार्य) "पुस्तकालयों को बता रहा है कि आप क्या चाहते हैं" (कार्यात्मक)

तो छोरों का उपयोग करने के बजाय आपको स्टॉल में मौजूद एल्गोरिदम सीखना चाहिए।

कंटेनर स्वतंत्रता के लिए

मैं हमेशा सरणी सूचकांक का उपयोग करता हूं क्योंकि मेरा कुछ अनुप्रयोग "डिस्प्ले थंबनेल छवि" की तरह कुछ आवश्यक है तो मैंने ऐसा कुछ लिखा था:

 some_vector[0].left=0; some_vector[0].top =0;<br> for (int i = 1; i < some_vector.size(); i++) { some_vector[i].left = some_vector[i-1].width + some_vector[i-1].left; if(i % 6 ==0) { some_vector[i].top = some_vector[i].top.height + some_vector[i].top; some_vector[i].left = 0; } } 

दोनों लागूकरण सही हैं, लेकिन मैं 'के लिए' लूप को पसंद करता हूं। जैसा कि हमने एक वेक्टर का उपयोग करने का निर्णय लिया है और किसी अन्य कंटेनर का उपयोग नहीं किया है, अनुक्रमित का उपयोग करना सबसे अच्छा विकल्प होगा। वेक्टरों के साथ इटेरेटर्स का उपयोग करना लगातार स्मृति ब्लॉकों में ऑब्जेक्ट होने का बहुत लाभ खो देगा जो उनकी पहुंच में आसानी से मदद करते हैं।

  • यदि आप धातु के करीब होने की तरह / अपने कार्यान्वयन के विवरण पर भरोसा नहीं करते हैं, तो इटेरेटर का उपयोग न करें
  • यदि आप नियमित रूप से विकास के दौरान एक संग्रह प्रकार को दूसरे के लिए स्विच करते हैं, तो इटेरेटर का उपयोग करें
  • यदि आपको याद रखना मुश्किल लगता है कि संग्रह के विभिन्न प्रकारों को पुनरावृति कैसे करें (हो सकता है कि आपके पास कई अलग-अलग बाहरी स्रोतों में से कई प्रकार हैं), उन तरीकों को एकजुट करने के लिए उपयोग करें , जिनके द्वारा आप तत्वों पर चलते हैं यह एक सरणी सूची के साथ एक लिंक की गई सूची को स्विच करने के लिए कहने पर लागू होता है।

वास्तव में, यह सब वहाँ है ऐसा नहीं है कि आप औसतन अधिक समानताएं हासिल करने जा रहे हैं, और यदि संक्षिप्तता वास्तव में आपका लक्ष्य है, तो आप हमेशा मैक्रोज़ पर वापस आ सकते हैं।

कोई भी अभी तक उल्लेख नहीं किया है कि सूचकांक का एक फायदा यह है कि जब आप std::vector तरह एक कंटेनर कंटेनर में संलग्न होते हैं तो वे अमान्य नहीं होते हैं, ताकि आप पुनरावृत्त के दौरान कंटेनर में आइटम जोड़ सकते हैं।

यह इटरेटर के साथ भी संभव है, लेकिन आपको reserve() कॉल करना होगा, और इसलिए आपको पता होना चाहिए कि आप कितने आइटम जोड़ेंगे