8

ऐसा प्रतीत होता है कि इटरेटर एडाप्टर reverse_iterator दोगुनी इसके अधिकांश नेस्टेड प्रकारों को परिभाषित करता है। विशेष रूप से, यह std::iterator से सार्वजनिक रूप से विरासत में आता है जो iterator_category, value_type, difference_type, pointer और reference का खुलासा करता है। iterator_category और value_type के अलावा, ये कक्षा परिभाषा में सभी स्पष्ट रूप से typedef 'ed हैं।रिवर्स_इटरेटर अपने घोंसले प्रकार को दोगुना क्यों परिभाषित करता है?

24.5.1.1 कक्षा टेम्पलेट reverse_iterator [reverse.iterator]

namespace std { 
template <class Iterator> 
class reverse_iterator : public 
    iterator<typename iterator_traits<Iterator>::iterator_category, 
    typename iterator_traits<Iterator>::value_type, 
    typename iterator_traits<Iterator>::difference_type, 
    typename iterator_traits<Iterator>::pointer, 
    typename iterator_traits<Iterator>::reference> { 
public: 
    typedef Iterator           iterator_type; 
    typedef typename iterator_traits<Iterator>::difference_type difference_type; 
    typedef typename iterator_traits<Iterator>::reference  reference; 
    typedef typename iterator_traits<Iterator>::pointer   pointer; 
    // ... rest of the class 
}; 

प्रश्न: क्यों दोहराए परिभाषा? क्या यह सिर्फ प्रदर्शनी के प्रयोजनों के लिए है, या इसके लिए और भी कुछ है? और iterator_category और value_type को फिर से परिभाषित क्यों न करें?

+4

यह 'value_type' या तो फिर से परिभाषित नहीं है। वैसे भी, यह प्रश्न जल्द ही जल्द ही बन जाएगा, [एलडब्ल्यूजी 2438] (http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#2438) के लिए धन्यवाद। –

+0

@ टी.सी. डीआर खोदने के लिए धन्यवाद। मैंने क्यू को अपडेट किया। अगर आप इसे उत्तर देते हैं, तो मैं स्वीकार करूंगा। – TemplateRex

+5

शायद इसे आश्रित नाम लुकअप के साथ करना है? 'Iterator' से विरासत में नाम सभी मामलों में दिखाई नहीं दे रहे हैं, क्योंकि यह एक निर्भर आधार वर्ग है। – dyp

उत्तर

6

थोड़ी देर के लिए, वे बेस क्लास के रूप में std::iterator का उपयोग करने से दूर जा रहे हैं, और केवल यह निर्दिष्ट करने के लिए कि प्रत्येक इटरेटर को सही प्रकार के नामों को परिभाषित करना होगा।

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

यह (मेरे लिए) लगता है कि यह (कम या ज्यादा गलती से) एक आधार वर्ग के रूप में std::iterator के उपयोग की आवश्यकता होती है, और बस ऐसे नाम हैं जो चाहिए निर्दिष्ट करने से जाने की प्रक्रिया में और अधिक या कम एक आकस्मिक आधे रास्ते बिंदु है std::reverse_iterator (और कई अन्य इटेटर भी, निश्चित रूप से) में परिभाषित किया जाना चाहिए।

जो लोग परवाह के लिए, इस के इतिहास में शामिल हैं:

N3931
Issue 2438

वहाँ भी है unary_function और binary_function का बहिष्कार कर के बारे में तो संबंधित चर्चा पत्र:

N3145
N3198

ये पी थे लगभग std::iterator (यानी, केवल व्युत्पन्न वर्ग में कुछ टाइपिफ़ी प्रदान करने के लिए) के कारणों के लिए रोका गया है, इसलिए उन्हें हटाने के पीछे तर्क आधार श्रेणी के रूप में std::iterator का उपयोग करना बंद करना उचित है।

+0

'is_base_of को कॉल करने के लिए ट्रिकी' न तो प्रकार हैं। ;) 'Std :: iterator' का उपयोग करते समय मैं अपनी परिभाषाओं को खींचता हूं, क्योंकि मैं आंतरिक रूप से उनका उपयोग नहीं कर सकता (आश्रित नाम लुकअप के कारण) यदि मैं स्वयं एक टेम्पलेट हूं। – Yakk

+0

'reverse_iterator' की परिभाषा पहले से ही C++ 03 आईएस में इस तरह से हो चुकी है। – dyp

+0

@dyp: अब Google समूह की स्थिति को देखते हुए, मुझे यकीन नहीं है कि मैं इसे पा सकता हूं, लेकिन मुझे एक यूज़नेट थ्रेड याद है जो ऐसा लगता है कि यह लगभग 1 99 6 या उससे भी पहले था, पहले ही बहस कर रहा था कि ये एक गरीब विचार थे, और टाइपिफ सिर्फ सीधे निर्दिष्ट किया जाना चाहिए। –

3

यह अनुमान लगाया गया है, लेकिन उन सभी अनावश्यक typedefsreverse_iterator के वर्ग निकाय के विनिर्देशन के भीतर उपयोग किए जाने वाले सभी प्रकार की घोषणा करें। उदाहरण के लिए (सी ++ 03 है):

pointer operator->() const; 
reference operator[](difference_type n) const; 

iterator<..> के बाद से एक आश्रित आधार वर्ग है, यह नाम pointer और reference के लिए खोज नहीं किया जाएगा।तो typedef उन नामों ing शेष कल्पना सरल बनाता है:

typename iterator_traits<Iterator>::pointer operator->() const; 
typename iterator_traits<Iterator>::reference operator[](typename iterator_traits<Iterator>::difference_type n) const; 

दूसरी ओर, value_type, वर्ग शरीर के भीतर प्रकट नहीं होता है, इसलिए यह एक निरर्थक typedef जरूरत नहीं है।

+0

बेशक, यह इस सवाल का जवाब नहीं देता है कि पहली बार 'इटरेटर' से क्यों प्राप्त किया जाए .. लेकिन एक बार यह दिया गया है, 'टाइपिफ' सुविधा के लिए एक निहितार्थ है। – dyp

+0

'ऑपरेटर []' का रिटर्न प्रकार सी ++ 14 आईएस, बीटीडब्ल्यू में निर्दिष्ट नहीं है। – dyp

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