2012-09-24 11 views
5

मैं एक वेक्टरक्या मुझे इटरेटर या एक्सेस ऑपरेटर द्वारा वेक्टर को फिर से चालू करना चाहिए?

std::vector<int> MyVector; 
MyVector.push_back(5); 
MyVector.push_back(6); 
MyVector.push_back(7); 

मैं कैसे पाश के लिए एक में उपयोग करना चाहिए के रूप में घोषित किया गया है?

इसे एक पुनरावर्तक के साथ पुनरावृत्त करके?

for (std::vector<int>::iterator it=MyVector.begin(); it!=MyVector.end(); ++it) 
{ 
    std::cout << "Vector element (*it): " << *it << std::endl; 
} 

या इसके एक्सेस इटेटरेटर द्वारा?

for (std::vector<int>::size_type i=0; i<MyVector.size(); i++) 
{ 
    std::cout << "Vector element (i) : " << MyVector.at(i) << std::endl; 
} 

उदाहरणों में मैंने इंटरनेट पर पाया कि दोनों का उपयोग किया जाता है। क्या उनमें से एक सभी शर्तों के तहत दूसरे से बेहतर है? यदि नहीं, तो मुझे उनमें से एक को दूसरे पर कब प्राथमिकता दी जानी चाहिए?

+1

निर्णय के साथ नहीं नाम * "इटरेटर" * मदद करता है? वैसे, मुझे आशा है कि आपको स्पष्ट रूप से समझ होगी कि 'std :: vector :: at' क्या करता है और आप इसे अपने कोड में क्यों उपयोग करते हैं। यदि 'std :: vector :: ऑपरेटर []' के बजाय 'std :: vector :: at' का उपयोग कर रहे हैं, तो इटरेटर शायद अधिक तेज़ होंगे (किसी भी अन्य फायदे को अनदेखा कर रहे हैं)। –

उत्तर

5

पहले प्रारूप मानक पुस्तकालय कंटेनरों से अधिक पुनरावृत्ति तो यह अधिक सामान्य और सहज है के लिए अधिक सामान्य स्वरूप है। यदि आपको अपने कंटेनर को बदलने की ज़रूरत है तो यह पुनरावृत्त कोड unimpacted रहता है। यह प्रत्येक मानक लाइब्रेरी कंटेनर प्रकार के लिए काम करेगा, इस प्रकार यह आपको अधिक सामान्य कोड देता है।

दूसरे प्रारूप में, सीमा के लिए std::vector::at() चेकों हर बार हर यात्रा पर बुलाया जाता है, तो यह एक छोटे से प्रदर्शन के लिए हानिकारक हो सकता है। यह ओवरहेड पहले प्रारूप में मौजूद नहीं है क्योंकि इसमें कोई सीमा जांच शामिल नहीं है। नोट करें कि operator[] का उपयोग करने के मामले में ऐसा ही है।
प्रदर्शन अंतराल पर ध्यान दें, हालांकि आप इसे तब तक नहीं देख पाएंगे जब तक आप एक विशाल डेटा पर काम नहीं कर रहे हों।

+0

Concur। निचली पंक्ति: यादृच्छिक पहुंच के लिए स्कैनिंग के लिए इटरेटर का उपयोग करें। आप खुश होंगे कि आपने किया था। – WhozCraig

+0

@CraigNelson नहीं, मैं नहीं करूँगा। अगर मैं सीमाओं से बाहर वेक्टर तक पहुंचता हूं, तो मुझ पर शर्म (और यूबी), लेकिन मुझे हर बार अपना आकार जांचने की ज़रूरत नहीं है। डीबग मोड में मुझे वैसे भी एक दावा मिलेगा (कम से कम वीसी ++ में)। –

+0

@ क्रिस्टियन राउ यदि आप अपने व्यवसाय की सीमाओं को जानने के बिना यादृच्छिक-अनुक्रम तक पहुंच रहे हैं। मैं समय से पहले जानना पसंद करता हूं। हालांकि, आप काफी सही हैं। मैं() के बजाय [] कहना चाहता था। टच। – WhozCraig

3

std::vector's [] operator का उपयोग करना संभवतः तेज़ है क्योंकि std::vector::at() का उपयोग लूप के अंदर वेक्टर के आकार को दो बार (लूप के लिए और std :: vector :: में() की सीमाओं की जांच में चेक करता है)।

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

यदि आप सी ++ 11 का उपयोग करते हैं, तो श्रेणी-आधारित लूप का उपयोग करें।

2

पहले यदि आपके पास सी ++ 11, का उपयोग एक सीमा के आधार पर के लिए:

for (auto i : MyVector) 
{ 
    std::cout << i; 
} 

या BOOST_FOREACH सी ++ 03 में:

BOOST_FOREACH(int& i, MyVector) 
{ 
    std::cout << i; 
} 

या std::copy:

std::copy(MyVector.begin(), 
      MyVector.end(), 
      std::ostream_iterator<int>(std::cout, "\n")); 

के लिए, हाथ में सवाल, at() जांचता है कि सूचकांक सीमाओं और फेंक के भीतर है एक अपवाद अगर यह नहीं है। तो, इसका उपयोग तब तक न करें जब तक आपको उस अतिरिक्त जांच की आवश्यकता न हो। आपके पास पहला तरीका मानक है और अच्छी तरह से काम करता है। कुछ लोगों को पंडिताऊ हैं और यहां तक ​​कि यह ऐसा है जैसे लिखना:

for (std::vector<int>::iterator it=MyVector.begin(), end = MyVector.end(); it!= end; ++it) 
{ 
    std::cout << "Vector element (*it): " << *it << std::endl; 
} 

ऊपर में मैं बजाय end() प्रत्येक पाश बुलाने की end इटरेटर कैश की गई। चाहे यह वास्तव में प्रदर्शन अंतर करता है या नहीं, मुझे नहीं पता।

1

नहीं "एक अन्य से बेहतर है" (छोड़कर आप लगभग कभी उपयोग करने के लिए at()at() केवल उचित है, अगर वहाँ कुछ तुम सच में त्रुटि को ठीक करने के लिए क्या कर सकते हैं कि) नहीं है। इटरेटर बनाम इंडेक्स का उपयोग मोटे तौर पर स्टाइल में से एक है, और संदेश गुजर रहा है। चीजों को करने का अधिक मूर्खतापूर्ण सी ++ तरीका इटरेटर होगा, लेकिन अन्य पृष्ठभूमि से आने वाले लोग (उदाहरण के लिए, गणितज्ञ) को अधिक मूर्खतापूर्ण अनुक्रमण मिलेगा।

रहे हैं जहां एक असली फर्क नहीं है:

  • इटरेटर मुहावरा कंटेनरों के अन्य प्रकार के साथ काम करेंगे। यह प्रासंगिक हो सकता है यदि वास्तविक संभावना है कि आप अन्य कंटेनर का उपयोग करते हैं।

  • इंडेक्सिंग मुहावरे कई अलग-अलग कंटेनर के लिए एक एकल इंडेक्स का उपयोग कर सकता है। यदि आप vector के माध्यम से उसी आकार के साथ पुनरावृत्त कर रहे हैं, तो इंडेक्सिंग मुहावरे का उपयोग करके यह स्पष्ट हो जाता है कि आप vector में से प्रत्येक में एक ही तत्व तक पहुंच रहे हैं। शायद अधिक सहज ज्ञान युक्त है (फिर, यह गणितीय अनुप्रयोगों में सबसे अधिक बार घटित हो रहा है।)

  • अंत में, किसी भी समय आप वास्तव में रैंडम एक्सेस, कर रहे हैं या किसी भी तरह से तत्व की गणना, अनुक्रमित का उपयोग कर। ( ऐसे मामलों में, आप शायद int में गणना करने के लिए, चाहते केवल आखिरी समय पर size_t को बदलने।)

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

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