2011-10-19 8 views
6

ऐसे कोड है:लपेटें एसटीएल वेक्टर और इस परिवर्तन से उसकी इटरेटर के व्यवहार

#include <iostream> 
#include <vector> 

template <class T> 
class A{ 
public: 
    class iterator : public std::vector<T>::iterator{ 
    public: 
     T& operator*(){ 
      ?? 
     } 
    }; 

    iterator begin(){ 
     return v.begin(); // error 
    } 

    iterator end(){ 
     return v.end(); // error 
    } 

    void add(const T& elem){ 
     v.push_back(elem); 
    } 

private: 
    std::vector<T> v; 
}; 

int main() { 
    A<int> a; 
    a.add(2); 
    a.add(4); 
    for(A<int>::iterator it = a.begin(); it != a.end(); ++it){ 
     std::cout << *it << std::endl; 
    } 
    return 0; 
} 

यह मेरा खुद का अतिरिक्त कार्यों के साथ std::vector के लिए एक आवरण है। मैं std::vector के iterator उपयोग करना चाहते हैं, फिर भी मैं केवल चाहते इटरेटर के लिए operator* का व्यवहार बदलने के लिए:

T& operator*(){ 
    // do some additional function 
    // normal behavior, return value of some element in vector 
      ?? 
} 

मैं std::vector कैसे उपयोग कर सकते हैं और केवल operator* के संशोधन के साथ अपने इटरेटर? मैं इटरेटर के लिए begin() और end() जैसे कार्यों को लपेटना चाहूंगा, उन्हें सही ढंग से कैसे लपेटें?

संपादित करें:

#include <iostream> 
#include <vector> 

template <class T> 
class A { 
public: 

    class iterator : public std::vector<T>::iterator { 
    public: 

     iterator(typename std::vector<T>::iterator c) : std::vector<T>::iterator(c) { 
     } 

     T& operator*() { 
      std::cout << "Im overloaded operator*\n"; 
      return std::vector<T>::iterator::operator *(); 
     } 
    }; 

    iterator begin() { 
     return iterator(v.begin()); 
    } 

    iterator end() { 
     return iterator(v.end()); 
    } 

    void add(const T& elem) { 
     v.push_back(elem); 
    } 

private: 
    std::vector<T> v; 
}; 

int main() { 
    A<int> a; 
    a.add(2); 
    a.add(4); 

    for (A<int>::iterator it = a.begin(); it != a.end() ; ++it) { 
     std::cout << *it << std::endl; 
    } 
    return 0; 
} 

शायद यह किसी के लिए उपयोगी होगा:

इस विषय में जवाब से सुझाव का उपयोग करना, मैं निम्नलिखित तरीके से मेरी समस्या को हल करने में कामयाब रहे।

+0

यूप। मैंने कोड को गलत तरीके से पढ़ा। पता नहीं वो कैसे हुआ। –

उत्तर

3

रैपिंग स्टडीलिब इटरेटर्स इटेटरेटर एडाप्टर के साथ सबसे अच्छा किया जाता है। यह कार्य तुच्छ से बहुत दूर है और कार्य को सरल बनाने के लिए Boost.Iterator लाइब्रेरी है। शायद प्रदान किए गए इटरेटर में से एक आपकी समस्या को हल कर लेता है।

आप (मैं वास्तव में इस अनुशंसा नहीं करते हैं ) अपने दम पर यह लिख करने के लिए जा रहे हैं, तो आप अपने खुद के इटरेटर को लागू करने और यह एक vector::iterator से constructible होना चाहिए, तो आवश्यकताओं को पूरा करने के लिए सभी आवश्यक ऑपरेटरों को ओवरलोड अवधारणा के बारे में कि आपके नए इटरेटर मॉडल। गुणों को काम करने के लिए std::iterator से भी उत्तराधिकारी। एक कॉन्स संस्करण नहीं भूलना। This book में आपके स्वयं के इटरेटर विकसित करने के लिए समर्पित एक अध्याय है। मानक की एक प्रति प्राप्त करें (सी ++ 03 या सी ++ 11, इससे कोई फर्क नहीं पड़ता)। आपको इसकी आवश्यकता होगी।

+1

यदि वह इसे पारदर्शी रूप से उपयोग करना चाहता है (जिसे उसका प्रश्न सुझाता है) तो उसे 'std :: vector' के लिए एक रैपर लागू करने की भी आवश्यकता है)। –

+0

@ BjörnPollex कक्षा दिखती है कि उसे केवल एडाप्टर की आवश्यकता होगी। उनकी कक्षा को 'अनुक्रम' के पूर्ण मॉडल के रूप में नहीं माना जाता है और 'प्रारंभ() 'और' अंत() 'को उजागर करने के लिए केवल इटरेटर की आवश्यकता होती है। – pmr

1

दुर्भाग्यवश, ऐसा करने का एकमात्र तरीका std::vector और इसके पुनरावर्तक-प्रकार के लिए एक संपूर्ण रैपर लिखना है। यह बहुत काम है।

-1

मुझे लगता है कि यहां जवाब सबसे अधिक संभावना है कि ऑपरेटर के व्यवहार को एक इटरेटर के लिए परिवर्तित नहीं करना चाहिए। ऑपरेटर अधिभार केवल उन मामलों में किया जाना चाहिए जहां यह बेहद सहज है कि ऑपरेटर का उपयोग करने वाले कोड को पढ़ने वाले किसी भी व्यक्ति को स्वचालित रूप से पता चल जाएगा कि क्या हो रहा है। इसका एक उदाहरण होगा यदि आपके पास मैट्रिक्स क्लास और ओवरलोडेड ऑपरेटर + था। जब कोई आपको दो मैट्रिक्स ऑब्जेक्ट्स को एक साथ जोड़ता है, तो वे आसानी से जान सकते हैं कि क्या हो रहा है।

हालांकि एक पुनरावर्तक को अस्वीकार करते समय, आपके वर्ग के लिए अतिरिक्त साइड इफेक्ट्स के बारे में कोई सहज ज्ञान नहीं है।

+1

ओह, 'ऑपरेटर *' के व्यवहार को बदलना बेहद उपयोगी हो सकता है। 'रूपांतरण इटरेटर' सोचें। – pmr

1

कोई std::vector<T>::iterator से प्राप्त नहीं होता है क्योंकि इसे कक्षा होने की आवश्यकता नहीं है। कुछ कार्यान्वयन में यह T* के लिए सिर्फ एक टाइपिफ़ है, और कोई एक पॉइंटर से प्राप्त नहीं कर सकता है। एक को मानक कंटेनरों से भी उत्तराधिकारी नहीं होना चाहिए क्योंकि उनमें आभासी विनाशक की कमी है; private या protected तरीके से उत्तराधिकारी होने की संभावना है और typedef और using के माध्यम से सभी प्रतीकों और कार्यों को दृश्यमान बनाएं। अंत में, आपको पूरे वेक्टर और उसके इटरेटर्स को फिर से लिखना होगा जो बेस कार्यान्वयन को कॉल अग्रेषित करते हैं।

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