Pregunta Adaptador de desreferencia para iterador de punteros.


Tengo un contenedor que es responsable de administrar un conjunto de atributos. La clase se ve de forma parecida a esto:

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

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

El atributo es polimórfico, por lo que los atributos deben almacenarse como punteros, sin embargo, nunca pueden ser NULOS.

Quiero usar esta clase con BOOST_FOREACH, como esto:

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

De acuerdo con la documentación de BOOST_FOREACH,

El soporte para contenedores STL es muy general; todo lo que parece un contenedor de STL cuenta. Si ha anidado los tipos de iterador y const_iterator y las funciones de miembros begin () y end (), BOOST_FOREACH sabrá automáticamente cómo iterar sobre él.

Así que actualicé mi clase para ver algo como esto:

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

Entonces ahora puedo hacer esto:

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

Esto es bueno, pero no me gusta que expone los atributos como punteros. Desde el lado de la persona que llama, esto es ruido y generaría verificaciones NULL sin sentido.

Tengo algunas ideas sobre cómo corregir el problema. Por ejemplo, algo como esto sería agradable:

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 clase 'iterator_dereference_adapter' se explica por sí misma. Incluiría un iterador existente de punteros y eliminaría los valores del puntero.

Así que, finalmente, mi pregunta....

Antes de salir e intentar escribir este adaptador, ¿hay algo en STL o Boost como esta clase?

Estoy abierto a otras ideas.


5
2017-07-12 16:10


origen


Respuestas:


Boost tiene indirect_iterator que es exactamente necesario para envolver un iterador al tipo de puntero y desreferenciación automática.


7
2017-07-12 16:21