STL Iterator: The dereferencing iterator is temporary. Is it possible?

I am writing a 3D mesh for my scientific software, and I need to iterate through the nodes of the mesh to get their coordinates. Instead of holding each node object in the container, I'd rather just calculate the coordinates on the fly during the iteration. The problem is that stl :: iterator requires returning a reference to the value as a result of operator*() or a pointer to 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 retrieves node coordinates by index

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

Any input on this?

Thanks in advance, Ilya

+4
source share
4 answers

You can use a member variable to hold the grid point that it currently points 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 may look like this:

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

Thanks to @greg for indicating that CurrentPoint must be mutable for this to work. This would be a lazy implementation (only getting the point when the iterator is actually dereferenced). The expected implementation will update the CurrentPoint member in the iterator mutator methods ( operator++ options in this example), making mutable superfluous.

+5
source

Since the iterator is an object of value, why not just set the member to the value you want to return and return the link to the member?

+1
source

Short answer: this will lead to undefined behavior, you will all return a link to a temporary one! One option (if this iterator does not require re-entry, there should be a member of the class (of type spVector3D) to which you have "assigned" the return value (of course, you could do this more optimally by passing the link to this to GetPoint, as well as the index), and then return it.

+1
source

I know this post is too old, but just because I had the same "problems" and google brought me here, I will add my two cents, this is what I found:

At least in the C ++ library, there are many types of iterators, each of which declares some related semantics. Types

  • Input iterators
  • Iterators forward
  • Bidirectional iterators
  • Random access iterators
  • Output iterators

In your case, iterator input semantics work. In particular, in operator*() input iterators, there is no need to return a reference to an object; it can even return a newly created object. Thus, avoiding the presence of a “dummy” object inside an iterator object, as Björn suggested.

You can view it here .

+1
source

All Articles