Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dereference adapter for iterator of pointers

I have a container which is responsible for managing a set of attributes. The class partially looks something like this:

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

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

Attribute is polymorphic so the attributes have to be stored as pointers however they can never be NULL.

I want to use this class with BOOST_FOREACH, like this:

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

According to BOOST_FOREACH documentation,

The support for STL containers is very general; anything that looks like an STL container counts. If it has nested iterator and const_iterator types and begin() and end() member functions, BOOST_FOREACH will automatically know how to iterate over it.

So I updated my class to look something like this:

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

So now I can do this:

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

This is nice however I don't like that it exposes the attributes as pointers. From the caller side, this is noise and would generate pointless NULL checks.

I have a few ideas on how to correct the problem. For example, something like this would be nice:

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

The 'iterator_dereference_adapter' class is somewhat self-explanatory. It would wrap an existing iterator of pointers and dereference the pointer values.

So finally, my question...

Before I go off and try to write this adapter, is there something in STL or Boost like this class?

I'm open to other ideas.

like image 445
kede Avatar asked Jul 12 '13 16:07

kede


People also ask

Can you dereference an iterator?

Dereferencing: An input iterator can be dereferenced, using the operator * and -> as an rvalue to obtain the value stored at the position being pointed to by the iterator. 4. Incrementable: An input iterator can be incremented, so that it refers to the next element in the sequence, using operator ++().

What are iterator Adaptors?

Iterator adaptors for insertion (insert iterators) Inserters (also called "insert iterators") are "iterator adaptors" that permit algorithms (the copy algorithm, for example) to operate in insert mode rather than overwrite mode, which is the default.

Is a vector iterator a pointer?

An iterator is an object (like a pointer) that points to an element inside the container. We can use iterators to move through the contents of the container.


1 Answers

Boost has indirect_iterator which is exactly inteded for wrapping an iterator to pointer type and automatically dereferencing.

like image 200
Casey Avatar answered Sep 23 '22 02:09

Casey