2016-07-01 5 views
6

सी ++ में, हम इनपुट इटरेटर्स, फॉरवर्डइटरेटर और बिडरेक्शनल इटरेटर्स की तुलना करने के लिए '>' या '<' का उपयोग क्यों नहीं कर सकते? हालांकि, हम RandomAccessIterators की तुलना '>' या '<' से कर सकते हैं, उदाहरण के लिए std :: vector। इसके पीछे का कारण क्या है?सी ++ इटरेटर्स के बारे में प्रश्न

इसके अलावा, हम iterators की सामग्री क्यों नहीं कर सकते? जैसे कि "cout < < itr < < एंडल;" काम नहीं करेगा इसके पीछे का कारण क्या है? Iterators पॉइंटर्स की तरह बहुत हैं, लेकिन हम पॉइंटर्स cout कर सकते हैं लेकिन iterators नहीं, क्यों?

सामान्यतः, इटरेटर और पॉइंटर्स के बीच आंतरिक अंतर क्या है? मुझे लगता था कि वे समान हैं, लेकिन मुझे लगता है कि मुझे सी ++ समझने के अगले स्तर तक पहुंचने के लिए इसे समझना है।

प्रश्न # 2: सभी को भयानक उत्तरों के लिए धन्यवाद। इटरेटर के संबंध में मेरे पास एक और सवाल है। सी ++ क्यों कुछ "50397953" प्रिंट करता है जब इटरेटर सीमा से बाहर हो जाता है? क्या यह कुछ नल या '\ 0' प्रिंट नहीं करना चाहिए?

+0

दो आगे इटरेटर्स के लिए 'itr1 Beta

+0

धन्यवाद बीटा। यह एक प्राकृतिक जवाब है! – Thenewstockton

उत्तर

5

std::list<T> में बिडरेक्शनल इटरेटर्स हैं और यह तुलना करने योग्य होने की आवश्यकता के लिए कोई समझ नहीं आता है। यह भी स्पष्ट नहीं है कि इस तरह की आवश्यकता के अनुरूप होने के लिए std::list<T> को कार्यान्वित करना संभव होगा। हालांकि, चूंकि यादृच्छिक अभिगम इटरेटर्स घटाव का समर्थन करते हैं, यह स्पष्ट है कि हम उनकी तुलना कर सकते हैं।

हम एक पुनरावर्तक के मूल्य को क्यों मुद्रित नहीं कर सकते? आम तौर पर, यह लेखक पर निर्भर करता है कि इस तरह के एक ऑपरेशन का समर्थन करना है या नहीं। कई इटरेटर्स मूल रूप से पॉइंटर्स के चारों ओर पॉइंटर्स या रैपर के रूप में कार्यान्वित किए जाते हैं --- operator<< प्रदान करने के लिए उन्हें उपयोगकर्ता को कोई लाभ नहीं मिलेगा जो वे ऑब्जेक्ट के पते को आसानी से प्रिंट करके प्राप्त नहीं कर पाएंगे।

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

+0

धन्यवाद ब्रायन। लेकिन ऑपरेटर क्यों नहीं प्रदान करेगा << उपयोगकर्ता को कोई लाभ दें? मेमोरी एड्रेस कुछ प्रोग्रामर हर समय जांच नहीं करता है? – Thenewstockton

+2

@ तेनवेस्टॉकटन आप बस 'std :: cout << और * it' कर सकते हैं अगर आप इसे चाहते हैं। मेरे अनुभव में, यह अक्सर एक शॉर्टेंड प्रदान करने के लिए पर्याप्त उपयोगी नहीं है। – Brian

+0

@ मेरे अनुभव में तेनस्टॉकटन, आपके जैसी चीजें करते समय सुझाव देते हैं - बेस्पेक इटरेटर्स के लिए ऑपरेटर ओवरलोड प्रदान करना - अक्सर ऐसा लगता है कि यह लंबे समय तक अधिक उपयोगी होगा। ऐसा इसलिए है क्योंकि आप जो भी सामरिक वाक्य रचनात्मक नवाचारों को पुनरावर्तक सम्मेलन की अर्थपूर्ण रणनीति के खिलाफ काम करते हैं, उनमें शामिल हैं: [इटेटरेटर की धारणा] में कुछ वाक्यविन्यास जोड़ हैं (http://en.cppreference.com/w/cpp/iterator), मेरी राय में, अतिव्यापी अवधारणा के खिलाफ काम नहीं करना है, जैसा ऊपर बताया गया है: "पॉइंटर्स का एक सामान्यीकरण" है। मूल रूप से। – fish2000

3

दोनों कठोर, औपचारिक स्पष्टीकरण और व्यावहारिक दोनों हैं।

कठोर, औपचारिक स्पष्टीकरण

क्योंकि यह कैसे सी में निर्दिष्ट है ++ है कि।

व्यावहारिक स्पष्टीकरण

एक वेक्टर हमेशा सन्निहित स्मृति में संग्रहीत किया जाता है, परिभाषा के द्वारा। एक इटरेटर एक पॉइंटर जितना कम या कम होता है। इसलिए, वास्तविक अंतर्निहित स्मृति पतों की तुलना करके यह परिभाषित करना संभव है कि कौन सा पॉइंटर दूसरे सूचक से "कम" या "बड़ा" है।

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

std::ostream पर operator<< के साथ आप इटरेटर का उपयोग नहीं कर सकते हैं क्योंकि, यह अधिभार परिभाषित नहीं किया गया है।ध्यान दें कि आप हमेशा निम्न कार्य कर सकते हैं, इसके बजाय:

cout << &*itr << endl; 

यह संदर्भित तत्व के वास्तविक स्मृति पते को प्रारूपित करेगा। लेकिन यह वैसे भी संदिग्ध उपयोग का है। यह ज्यादातर अर्थहीन है।

+0

धन्यवाद सैम। लेकिन एसटीएल अधिभार को परिभाषित क्यों नहीं करेगा? मुझे पता है कि कोई भी * * itr का उपयोग कर पता मुद्रित कर सकता है। हालांकि, "cout << itr << endl;" का समर्थन करना स्वाभाविक नहीं है ? मुझे लगता है कि इसे पॉइंटर्स और इटरेटर्स के बीच अंतर के साथ करना है, लेकिन मुझे वास्तव में क्यों पता नहीं है क्यों? कृपया सहायता कीजिए! – Thenewstockton

+0

@ तेनवेस्टॉकटन: आपको ऐसा क्यों लगता है कि यह प्राकृतिक होगा? मुझे ऐसा नहीं लगता है। –

+0

@ बेंजामिन लिंडले वैसे, मुझे यही लगता है: आप "cout << ptr << end;" कर सकते हैं , इसलिए यह करना महत्वपूर्ण है "cout << itr << endl;" लेकिन यह काम नहीं करेगा। – Thenewstockton

1

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

सामान्यतः, इटरेटर और पॉइंटर्स के बीच आंतरिक अंतर क्या है? मुझे लगता था कि वे समान हैं, लेकिन मुझे लगता है कि मुझे सी ++ समझने के अगले स्तर तक पहुंचने के लिए इसे समझना है।

इटरेटर पॉइंटर्स का सामान्यीकरण हैं।

तुम भी इसके अलावा कि iterator implementation on github

देख सकते हैं, हम क्यों iterators 'सामग्री अदालत नहीं कर सकते? जैसे कि "cout < < itr < < एंडल;" काम नहीं करेगा इसके पीछे का कारण क्या है? Iterators पॉइंटर्स की तरह बहुत हैं, लेकिन हम पॉइंटर्स cout कर सकते हैं लेकिन iterators नहीं, क्यों?

तो, अंदर क्या हो रहा है, जैसा कि मैं समझता हूं, यह है कि इटेटरेटर एक वर्ग है जिसमें एक आइटम को पॉइंटर संग्रहीत करने वाला क्षेत्र होता है। '*' ऑपरेटर ओवरराइट किया गया है और पॉइंटर्स पते पर संग्रहीत मान देता है।

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