2013-07-12 10 views
5

Ho un contenitore che è responsabile della gestione di un set di attributi. La classe si presenta parzialmente o meno così:Adattatore di deviazione per iteratore di puntatori

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

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

attributo è polimorfico così gli attributi devono essere memorizzati come puntatori tuttavia essi non possono mai essere NULL.

voglio usare questa classe con BOOST_FOREACH, in questo modo:

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

Secondo la documentazione BOOST_FOREACH,

Il supporto per i contenitori STL è molto generale; conta tutto ciò che sembra un contenitore STL. Se ha nested iterator e const_iterator types e begin() e end() funzioni membro, BOOST_FOREACH saprà automaticamente come iterare su di esso.

Così ho aggiornato la mia classe a cercare qualcosa di simile:

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; 
}; 

Così ora posso fare questo:

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

Questo è bello ma non mi piace che espone gli attributi come puntatori. Dal lato del chiamante, questo è rumore e genererebbe inutili verifiche NULL.

Ho alcune idee su come correggere il problema. Ad esempio, una cosa del genere sarebbe bello:

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; 
}; 

La classe 'iterator_dereference_adapter' è un po 'auto-esplicativo. Dovrebbe avvolgere un iteratore esistente di puntatori e dereferenziare i valori del puntatore.

Così alla fine, la mia domanda ...

Prima di andare fuori e cerco di scrivere questo adattatore, c'è qualcosa in STL o Boost come questa classe?

Sono aperto ad altre idee.

+5

Boost ha un [iteratore indiretto] (http://www.boost.org/doc/libs/1_54_0/libs/iterator/doc/indirect_iterator.html). –

+0

Bella domanda. +1. –

risposta

7

Boost ha indirect_iterator che è esattamente inteso per il wrapping di un iteratore per il tipo di puntatore e il dereferenziamento automatico.