简体   繁体   中英

STL algorithm to repeat an erase operation on a second container?

Life gave me the following objects:

  • std::vector<T1> v1;
  • std::vector<T2> v2;
  • typename std::vector<T1>::iterator it_first;
  • typename std::vector<T1>::iterator it_last;

and the following constraints:

  • v1.size() == v2.size() > 0
  • v1.begin() <= it_first <= it_last <= v1.end()

Removing from v1 the range pointed by the two iterators is a trivial single line, but how do I remove the same range also from v2 ?

I can easily solve this for instance by building v2 iterators using a mix of std::distance/advance , but I was wondering if the STL provides some machinery for this. Something like the erase-remove idiom coupled with a transform operation, maybe? It seems beyond my STL-fu...

When you have an iterator, then you can get the index via std::distance to begin() .

When you have an index, then you can get the iterator via begin() + index .

Thats bascially all you need to get the same range of incdices in the second vector.

Btw iterators are to abstract away the index. When you need the index, then work with the index. For erase that would be

size_t start = 1;
size_t end = 42;
std::erase( v1.begin() + start, v1.begin() + end );
std::erase( v2.begin() + start, v2.begin() + end );

I can easily solve this for instance by building v2 iterators using a mix of std::distance/advance, but I was wondering if the STL provides some machinery for this. Something like the erase-remove idiom coupled with a transform operation, maybe? It seems beyond my STL-fu...

I saw the edit only after writing the answer. The thing is std::distance / std::advance is the machinery to switch between iterators and indices.

Consider that iterators in general are for things that can be iterated. You do not even necesarily need a container to iterate. For example you could write an iterator type that lets you iterate integers. This iterator type could be used like this:

std::vector<std::string> x(100);
auto begin = int_iterator(0);
auto end   = int_iterator(100);
for ( ; begin != end; ++begin) std::cout << x[ *begin ];

This is no C-ism. The example is perhaps not the best, but the int_iterator itself is on par with the general concept of iterators. Usually iterators have no knowledge about the underlying container (if there is one). There are few exceptions (eg insert_iterator ). And in case of erase of course you need to pass iterators that refer to element in the corresponding container.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM