2011-12-16 24 views
9

मैं iterators के लिए एक पतली टेम्पलेट आवरण लिख रहा हूँ, और एक बड़ी बाधा मारा जब संरचना भिन्नता ऑपरेटर के माध्यम से गुजर, जिसका मुख्य कारण संकेत नहीं है एक:संरचना भिन्नता ऑपरेटर (ऑपरेटर>)

#include <vector> 

struct mystruct { 
    int member; 
}; 

template<class iterator> 
struct wrap { 
    typedef typename std::iterator_traits<iterator>::pointer pointer; 
    iterator internal; 
    pointer operator->() {return internal.operator->();} //MARK1 
}; 

int main() { 
    wrap<std::vector<mystruct>::iterator> a; 
    a->member; 
    wrap<mystruct*> b; 
    b->member; 
    return 0; 
} 

http://ideone.com/XdvEz

prog.cpp: In member function ‘typename std::iterator_traits<_Iter>::pointer wrap<iterator>::operator->() [with iterator = mystruct*]’: 
prog.cpp:18: instantiated from here 
prog.cpp:11: error: request for member ‘operator->’ in ‘((wrap<mystruct*>*)this)->wrap<mystruct*>::internal’, which is of non-class type ‘mystruct*’ 

यह निम्न विधि काम करता है, लेकिन मुझे नहीं लगता है कि यह काम करने के लिए गारंटी है है। अर्थात्, अगर एक इटरेटर के पास एक अजीब pointer प्रकार है जो value_type पर पॉइंटर के समान नहीं है।

pointer operator->() {return &*internal;} //MARK3 
+1

सी ++ के किन संस्करणों का एक * संरचना भिन्नता ऑपरेटर है *? –

+0

क्यों 'char * '? क्या कहीं कुछ 'Iterator :: value_type' नहीं होगा? –

+3

@ थॉमस मैथ्यूज: यही वही है [विकिपीडिया] (http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B#Member_and_pointer_operators) इसे कॉल करता है। सी ++ मानक बस इसे 'ऑपरेटर->' कहते हैं। –

उत्तर

10

मानक परोक्ष रूप से कहते हैं एक ओवरलोड operator-> या तो एक सूचक, एक वस्तु है कि एक सूचक है, या एक उद्देश्य यह है कि operator-> अतिभारित है के लिए परिवर्तनीय है वापस जाने के लिए है। आपकी सबसे अच्छी शर्त सिर्फ internal लौटना है।

§13.5.6 [over.ref] p1

कोई व्यंजक x->m(x.operator->())->m

के रूप में व्याख्या की है (जैसा कि ऊपर रिकर्सिवली लागू होता है।)

+0

और इससे पहले कि आप 'ऑपरेटर *()' के बारे में पूछें, वापसी का प्रकार 'iterator_traits :: संदर्भ' है और केवल' * iterator' लौटाएं। कोई भी पुनरावर्तक जो dereference पर 'संदर्भ' वापस नहीं करता है, यह इटरेटर अवधारणा को सही तरीके से मॉडल नहीं करता है और इसे आसानी से अनदेखा किया जा सकता है। – Xeo

+0

हाँ, मुझे 'ऑपरेटर *' मिला, लेकिन यह 'पॉइंटर' के बजाय 'इटरेटर' वापस करने के लिए कभी नहीं आया। धन्यवाद! मुझे उम्मीद है कि यह जवाब है लेकिन मैं इसे अन्य सुझावों के लिए एक दिन या तो देने की कोशिश करूंगा। –

+0

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

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