STL Vector, Iterator and Insert (C ++)

I have a method to which a vector iterator is passed. In this method, I would like to add some elements to the vector, but I'm not sure if this is possible only with an iterator

void GUIComponentText::AddAttributes(vector<GUIComponentAttribute*>::iterator begin, vector<GUIComponentAttribute*>::iterator end) { for (vector<GUIComponentAttribute*>::iterator i = begin; i != end; ++i) { GUIComponentAttribute &attrib = *(*i); // Here are the GUIComponentAttribute objects analyzed - if an object of a // special kind appears, I would like to add some elements to the vector } } 

Thanks Marcus

+4
source share
4 answers

First you will need to change the interface. Given the two iterators, there is no way to return to the container to which they belong; so if you want to change the container, you have to pass a link to it, that is :.

 void GUIComponentText::AddAttributes( std::vector<GUIComponentAttribute*>& attributes ) { for ( std::vector<GUIComponentAttribute*>::iter = attributes.begin(); iter != attributes.end(); ++ iter ) { // ... } } 

By doing this: insertion can invalidate iterators. So it depends on where you want to insert. If you want to insert position: std::vector<>::insert one element returns an iterator to this element that was inserted before your element, so that you can assign it to your iterator, configure (if necessary) and continue:

 iter = attributes.insert(iter, newAttribute); ++ iter; // Return to where we were... 

If you add ( push_back ), the problem is a bit more complicated; you need to calculate the offset and then restore the iterator:

 size_t offset = iter - attributes.begin(); attributes.push_back( nweAttribute ); iter = attributes.begin() + offset; 

In this case, it is probably easier to iterate with size_t and [] , rather than an iterator.

+2
source

In the code you show, this is not possible. Moreover, you should not add / remove elements to / from the vector while you iterate over it.

+4
source

This is a long-standing design problem in STL. Iterators do not allow changing the structure of the basic sequence that they iterate: i.e. you can change (sometimes) the elements themselves, but you cannot add / remove elements. Although InputIterator and OutputIterator bit special in this regard ... hum ...

This is actually the reason for the erase/remove idiom:

 vec.erase(std::remove_if(vec.begin(), vec.end(), predicate), vec.end()); 

So no, sorry, there is no way to really change the vector.

However, as shown above, you can make excellent use of the remove_if algorithm and just return the new end of the valid range ... or you can ask the whole vector to start with.

As noted by Bjรถrn, changing the structure of a sequence while iterating over it is error prone.

+3
source

It is not possible to add elements to a vector, iterating over it. In addition, you certainly cannot add it to a vector with a pair of iterators - you will need a pointer / link to the entire vector object.

The best you can do is return a vector of new components to add by the calling function.

0
source

Source: https://habr.com/ru/post/1382861/


All Articles