2012-07-11 16 views
9

निम्न क्रम पर विचार करें:मैं एक इटरेटर रैपर कैसे लिख सकता हूं जो अंतर्निहित इटरेटर से अनुक्रमिक मानों के समूह को जोड़ता है?

1, 2, 3, 4, 5, 6, 7, 8, 9, 10 

मुझे लगता है कि दृश्य के लिए इनपुट iterators है। मैं iterators कि निम्न क्रम के बजाय उत्पादन पर उन iterators रैप करने के लिए करना चाहते हैं:

(1,2), (3,4), (5,6), (7,8), (9,10) 

तो यह स्पष्ट नहीं है, इस क्रम मूल एक से लगातार तत्वों की क्रमागत जोड़ी का एक क्रम है। मूल में 10 तत्व हैं जबकि इसमें 5 है: प्रत्येक को मूल अनुक्रम से दो से प्राप्त किया जाता है।

मैं इस लागू करने के लिए बूस्ट के iterator_facade उपयोग कर रहा हूँ, और मैं इस पर यह गलत प्रयास है: जब इटरेटर है में पारित:

template <typename Iterator> 
    struct pairing_iterator 
    : boost::iterator_facade< 
     pairing_iterator<Iterator>, 
     std::array<typename std::iterator_traits<Iterator>::value_type, 2>, 
     std::input_iterator_category 
     // I should probably customize reference too, but it's not relevant 
    > { 
     pairing_iterator(Iterator it) : it(it) { 
      increment(); // A 
     } 
     pairing_iterator::value_type dereference() const { 
      return pair; 
     } 
     bool equal(pairing_iterator const& that) const { 
      return it == that.it; // B 
     } 
     void increment() { 
      pair = { { *it++, *it++ } }; 
     } 
     Iterator it; 
     pairing_iterator::value_type pair; 
    }; 

एक समस्या यह है कि मैं का सामना करना पड़ रहा है लाइन एक साथ चिह्नित पर है एक अंत इटरेटर, इसके परिणामस्वरूप इसे बढ़ाना होगा, जो मैं नहीं कर सकता।

बी के साथ चिह्नित रेखा पर एक और है: मैं अंतर्निहित पुनरावर्तक को हमेशा "वर्तमान" जोड़ी से आगे रख रहा हूं, इसलिए अगर इटेटरेटर आखिरी जोड़ी पर है, तो अंतर्निहित पुनरावर्तक एक अंतिम इटरेटर होगा, और इस प्रकार एक अंत pairing_iterator के खिलाफ सच की तुलना करें।

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

क्या मैं एक ऐसे पहिये को फिर से शुरू कर रहा हूं जो पहले से मौजूद है? मुझे बूस्ट में ऐसा कुछ नहीं मिला, जो मुझे थोड़ा आश्चर्यचकित करता है। लेकिन मुझे एक तैयार समाधान मिलना अच्छा लगेगा।

यदि यह पहिया पहले से बाहर नहीं है, तो मैं इसे वास्तव में रोल करने के लिए कैसे प्राप्त कर सकता हूं?

+0

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

+0

'इंटीजर डेरफरेंस() '? –

+0

@ डेविड ओप्स, यह मेरे द्वारा एक आर्टिफैक्ट था, उदाहरण से दूर अनावश्यक विवरण खरीदारी :) –

उत्तर

1

मैं दो सुझाव आप पहले से ही चैट में मार गिराया, एक अजीब लेकिन अपेक्षाकृत सुरक्षित सीमा से एक है, और सीमा के लिए एक बदसूरत वैकल्पिक हल के साथ एक है:

पहले विचार बहुत आसान है, लेकिन इससे पहले ठीक एक भिन्नता की आवश्यकता है प्रत्येक अग्रिम

template <typename Iterator> 
struct pairing_iterator 
: boost::iterator_facade< 
    pairing_iterator<Iterator>, 
    std::array<typename std::iterator_traits<Iterator>::value_type, 2>, 
    std::input_iterator_category 
    // I should probably customize reference too, but it's not relevant 
> { 
    pairing_iterator(Iterator it) : it(it) { 
    } 
    pairing_iterator::value_type dereference() const { 
     auto t = *it++; 
     return { { std::move(t), *it } }; 
    } 
    bool equal(pairing_iterator const& that) const { 
     return it == that.it; 
    } 
    void increment() { 
     ++it; 
    } 
    Iterator it; 
}; 

दूसरा विचार ठीक एक भिन्नता सीमा निकालता है, लेकिन बदसूरत और अजीब है:

template <typename Iterator> 
struct pairing_iterator 
: boost::iterator_facade< 
    pairing_iterator<Iterator>, 
    std::array<typename std::iterator_traits<Iterator>::value_type, 2>, 
    std::input_iterator_category 
    // I should probably customize reference too, but it's not relevant 
> { 
    pairing_iterator(Iterator it) : it(it), dereferenced(false) { 
    } 
    pairing_iterator::value_type dereference() const { 
     if (!dereferenced) { 
      auto t = *it++; 
      pair = { { std::move(t), *it } }; 
      dereferenced = true; 
     } 
     return pair; 
    } 
    bool equal(pairing_iterator const& that) const { 
     return it == that.it; 
    } 
    void increment() { 
     if (!dereferenced) 
      dereference(); 
     dereferenced = false; 
     ++it; 
    } 
    Iterator it; 
    pairing_iterator::value_type pair; 
    bool dereferenced; 
}; 

मैं probab ly ने कई त्रुटियां की, लेकिन उम्मीद है कि यह अवधारणाओं को चित्रित करने के लिए पर्याप्त है।

+0

{{* यह ++, * यह}}; प्रत्येक फ़ील्ड के लिए एक ही तत्व लौटाएगा (या अपरिभाषित है) क्योंकि ++ ';' के बाद तक नहीं होता है ... – bytemaster

+0

@bytemaster: मुझे यकीन नहीं है कि आप सही हैं, लेकिन बस मामले में, मैंने तय किया यह। यह एक छोटा बदलाव है। –

+0

@bytemaster नहीं, '{}' के भीतर मूल्यांकन का क्रम अच्छी तरह परिभाषित है। –

-1
template<typename T> 
struct piterator { 
    typedef std::pair<typename std::iterator_traits<T>::value_type, 
        typename std::iterator_traits<T>::value_type> value_type; 

    piterator(){} 
    piterator(const T& t, const T& e):itr(t),eitr(e){ 
    if(itr != eitr) head.first = *itr; 
    if(itr != eitr)head.second = *(++itr); 
    } 
    bool operator ==(const piterator& e)const { 
     return e.itr == itr && e.eitr== eitr; 
    } 

    value_type& operator*(){ return head; } 
    const value_type& operator*()const { return head; } 
    value_type& operator->(){ return head; } 
    const value_type& operator->()const { return head; } 

    piterator& operator++() { 
     if(itr != eitr)head.first = *(++itr); 
     if(itr != eitr)head.second = *(++itr); 
     return *this; 
    } 
    piterator& operator++(int) { 
     if(itr != eitr)head.first = *(++itr); 
     if(itr != eitr)head.second = *(++itr); 
     return *this; 
    } 
    private: 
    T itr; 
    T eitr; 
    value_type head; 
}; 

अतिरिक्त चेकों सुनिश्चित करें कि जोड़ी इटरेटर एक अजीब आकार सूची की 'अंत अतीत जाना' नहीं था बनाने के लिए की आवश्यकता होगी।

+0

* end * 'piterator' जैसा दिखता है? AFAICT, यह सीधे निर्माता से अपरिभाषित व्यवहार होगा। –

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