Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

STL iterator: "dereferencing" iterator to a temporary. Is it possible?

Tags:

c++

iterator

stl

I'm writing a 3D grid for my scientific software and I need to iterate through the nodes of the grid to get their coordinates. Instead of holding each node object in the container I'd rather like to just calculate the coordinates on the fly while iterating. The problem is that stl::iterator requires to return reference to a value as a result of operator*(), or pointer for operator->().

Some of the code below:


class spGridIterator {
public:
    typedef forward_iterator_tag iterator_category;
    typedef spVector3D value_type;
    typedef int difference_type;
    typedef spVector3D* pointer;
    typedef spVector3D& reference;

    spGridIterator(spGrid* gr, int index);

    spGridIterator& operator++();
    spGridIterator& operator++(int);

    reference operator*() const;
    pointer operator->() const;

private:
    spGrid* m_grid;
    int m_idx;
};

spGridIterator::reference spGridIterator::operator*() const {
    // return m_grid->GetPoint(m_idx);
}

spGridIterator::pointer spGridIterator::operator->() const {
    // return m_grid->GetPoint(m_idx);
}

This method queries the node coordinates by index provided


spVector3D spGrid::GetPoint(int idx) const {
    // spVector3D vec = ... calculate the coordinates here ...
    return vec;
}

Any input on this?

Thanks in advance, Ilya

like image 830
ezpresso Avatar asked Oct 29 '10 09:10

ezpresso


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 the STL iterators and what is their purpose?

An iterator is used to point to the memory address of the STL container classes. For better understanding, you can relate them with a pointer, to some extent. Iterators act as a bridge that connects algorithms to STL containers and allows the modifications of the data present inside the container.

Which STL function returns an iterator?

end(): The end() function returns an iterator pointing to the past-the-last element of the container.


1 Answers

You could use a member variable to hold the grid point it is currently pointing to:

class spGridIterator {
public:
    typedef forward_iterator_tag iterator_category;
    typedef spVector3D value_type;
    typedef int difference_type;
    typedef spVector3D* pointer;
    typedef const spVector3D* const_pointer;
    typedef const spVector3D& const_reference;
    typedef spVector3D& reference;

    spGridIterator(spGrid* gr, int index);

    spGridIterator& operator++();
    spGridIterator& operator++(int);

    reference operator*();
    const_reference operator*() const;

    pointer operator->();
    const_pointer operator->() const;

private:
    spGrid* m_grid;
    int m_idx;
    mutable spVector3D CurrentPoint;
};

Then the dereference operator could look like this:

spGridIterator::const_reference spGridIterator::operator*() const {
    CurrentPoint = m_grid->GetPoint(m_idx);
    return CurrentPoint;
}

Thanks to @greg for pointing out that CurrentPoint needs to be mutable for this to work. This would be a lazy implementation (only retrieving the point when the iterator is actually dereferenced). An eager implementation would update the CurrentPoint member in the mutator methods of the iterator (the operator++ variants in this example), making the mutable superfluous.

like image 126
Björn Pollex Avatar answered Oct 13 '22 10:10

Björn Pollex