सी ++ - स्टाइल इटरेटर्स के साथ गतिशील बहुरूपता होना मुश्किल है। operator++(int)
मूल्य से लौटाता है, जो afaik अव्यवस्थित है: आपके पास वर्चुअल सदस्य फ़ंक्शन नहीं हो सकता है जो *this
को बिना कटाई के मान देता है।
यदि संभव हो, तो मैं टेम्पलेट का उपयोग करने की सलाह देता हूं क्योंकि हर कोई कहता है।
लेकिन यदि आप गतिशील बहुरूपता, उदाहरण के लिए की जरूरत है, क्योंकि आप add_all_msgs के कार्यान्वयन का खुलासा नहीं कर सकते हैं के रूप में एक टेम्पलेट करना होगा, तो मुझे लगता है कि आप जावा होने का नाटक कर सकता है, इस तरह कार्य करें:
struct MessageIterator {
virtual Message &get() = 0;
virtual void next() = 0;
// add more functions if you need more than a Forward Iterator.
virtual ~MessageIterator() { }; // Not currently needed, but best be safe
};
// implementation elsewhere. Uses get() and next() instead of * and ++
void add_all_msgs(MessageIterator &it);
template <typename T>
struct Adaptor : public MessageIterator {
typename T::iterator wrapped;
Adaptor(typename T::iterator w) : wrapped(w) { }
virtual Message &get() {
return *wrapped;
}
virtual void next() {
++wrapped;
}
};
int main() {
std::deque<Message> v;
Adaptor<std::deque<Message> > a(v.begin());
add_all_msgs(a);
}
मैंने जांच की है कि यह संकलित है, लेकिन मैंने इसका परीक्षण नहीं किया है और मैंने पहले कभी इस डिज़ाइन का उपयोग नहीं किया है। मैंने कॉन्स-नेस से भी परेशान नहीं किया है - अभ्यास में आप शायद const Message &get() const
चाहते हैं। और फिलहाल एडाप्टर को रोकने के बारे में जानने का कोई तरीका नहीं है, लेकिन फिर आपके द्वारा शुरू किया गया कोड न तो करता है, इसलिए मैंने उसे भी अनदेखा कर दिया है। असल में आपको hasNext
फ़ंक्शन की आवश्यकता होगी जो कि wrapped
की तुलना में कन्स्ट्रक्टर को प्रदान किए गए अंत इटरेटर के विरुद्ध तुलना करेगी।
आप टेम्पलेट फ़ंक्शन और कॉन्स संदर्भों के साथ कुछ करने में सक्षम हो सकते हैं, ताकि ग्राहक को उस ग़लत एडाप्टर प्रकार के बारे में जानना या घोषित न हो।
[संपादित करें: इसके बारे में सोचने के लिए आओ, शायद add_all_msgs
फ़ंक्शन टेम्पलेट होना बेहतर है, जो एडाप्टर में अपना पैरामीटर लपेटता है और फिर real_add_all_msgs
पर कॉल करता है। यह पूरी तरह से क्लाइंट से एडाप्टर को छुपाता है।]
स्रोत
2009-07-09 15:27:43
कन्वेंशन संदर्भ के बजाय मानकों को मूल्य से लेना है।इसके अलावा, इटेटरेटर सामान्य रूप से "छोटे" होते हैं, इसके कारण (afaik) कॉलर को अस्थायी रूप से पास करने की अनुमति देना है, जैसे std :: back_inserter से वापसी मान। सी ++ 0x कम से कम दो तरीकों से इस बारे में सोच सकता है। –
हे, या "शुरूआत" से वापसी मूल्य इसके बारे में सोचने के लिए आते हैं। उपर्युक्त "उपयोग" कोड संकलित नहीं करता है: "अस्थायी प्रकार 'blah' प्रकार के गैर-कॉन्स्ट संदर्भ के प्रकार 'blah' के अमान्य प्रारंभिक 'blah'। –
ओपी ने स्पष्ट रूप से कहा: "जब तक इटेटरेटर संदेश पुनरावृत्त कर रहा है"। इस समाधान, और अन्य लोगों ने, इस आवश्यकता को पूरी तरह से अनदेखा कर दिया। –