2013-07-12 25 views
5

Posiadam kontener, który odpowiada za zarządzanie zestawem atrybutów. Klasa częściowo wygląda mniej więcej tak:Adapter przejściowy dla iteratora wskaźników

class AttributeSet 
{ 
public: 
    // ... interface is irrelevant for my question. 

private: 
    std::vector<boost::shared_ptr<Attribute> > m_attributes; 
}; 

Atrybut jest polimorficzny więc atrybuty muszą być przechowywane jako wskaźniki jednak nigdy nie może być null.

Chcę skorzystać z tej klasy z BOOST_FOREACH coś takiego:

BOOST_FOREACH(const Attribute &attribute, attributeSet) 
{ 
    ... 
} 

Według dokumentacji BOOST_FOREACH,

Wsparcie dla kontenerów STL jest bardzo ogólna; wszystko, co wygląda jak kontener STL, się liczy. Jeśli ma zagnieżdżone typy iteratorów i const_iterator oraz funkcje funkcji begin() i end(), BOOST_FOREACH będzie automatycznie wiedział, jak iterować po nim.

Więc aktualizowane moją klasę wyglądać mniej więcej tak:

class AttributeSet 
{ 
public: 
    typedef std::vector<boost::shared_ptr<Attribute> > container; 
    typedef container::iterator iterator; 
    typedef container::const_iterator const_iterator; 

    iterator begin(); 
    iterator end(); 

    const_iterator begin() const; 
    const_iterator end() const; 

private: 
    container m_attributes; 
}; 

Więc teraz mogę to zrobić:

BOOST_FOREACH(const boost::shared_ptr<Attribute> &attribute, attributeSet) 
{ 
    ... 
} 

Jest miły, jednak nie podoba mi się to, że eksponuje atrybuty jako wskaźniki. Od strony wywołującej jest to szum i generuje bezcelowe kontrole NULL.

Mam kilka pomysłów, jak rozwiązać problem. Na przykład coś takiego byłoby miło:

class AttributeSet 
{ 
public: 
    typedef std::vector<boost::shared_ptr<Attribute> > container; 
    typedef iterator_dereference_adapter<container::iterator> iterator; 
    typedef iterator_dereference_adapter<container::const_iterator> const_iterator; 

    iterator begin() { return iterator(m_attributes.begin()); } 
    iterator end() { return iterator(m_attributes.end()); } 

    const_iterator begin() const { return const_iterator(m_attributes.begin()); } 
    const_iterator end() const { return const_iterator(m_attributes.end()); } 

private: 
    container m_attributes; 
}; 

Klasa „iterator_dereference_adapter” jest dość oczywista. Zawijałby istniejący iterator wskaźników i dereferencji wartości wskaźników.

Więc wreszcie moje pytanie ...

Zanim zgaśnie i spróbuj napisać ten adapter, czy istnieje coś w STL lub zwiększyć jak do tej klasy?

Jestem otwarty na inne pomysły.

+5

Boost ma [pośredni iterator] (http://www.boost.org/doc/libs/1_54_0/libs/iterator/doc/indirect_iterator.html). –

+0

Ładne pytanie. +1. –

Odpowiedz

7

Funkcja Boost ma indirect_iterator, która jest dokładnie przewidziana do zawijania iteratora do typu wskaźnika i automatycznego dereferencji.

Powiązane problemy