Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Erasing vector::end from vector

Does it works correct(does nothing) when I use

 vector<T> v;  v.erase(v.end()); 

I want to use something like

 v.erase(std::find(...)); 

Should I if is it v.end() or not?
There is no info about it on C++.com and CPPreference

like image 285
RiaD Avatar asked Mar 06 '12 19:03

RiaD


People also ask

How do I remove an end element from a vector?

Description. The C++ function std::vector::pop_back() removes last element from vector and reduces size of vector by one.

How do you remove a vector from a vector?

All the elements of the vector are removed using clear() function. erase() function, on the other hand, is used to remove specific elements from the container or a range of elements from the container, thus reducing its size by the number of elements removed.

How do you remove a specific element from a vector in C++?

The C++ vector has many member functions. Two of these member functions are erase() and pop_back(). pop_back() removes the last element from the vector. In order to remove all the elements from the vector, using pop_back(), the pop_back() function has to be repeated the number of times there are elements.

What does vector erase do C++?

vector::eraseErases the specified elements from the container. 1) Removes the element at pos . 2) Removes the elements in the range [first, last) . Invalidates iterators and references at or after the point of the erase, including the end() iterator. The iterator pos must be valid and dereferenceable.


2 Answers

The standard doesn't quite spell it out, but v.erase(q) is defined, "Erases the element pointed to by q" in [sequence.reqmts]. This means that q must actually point to an element, which the end iterator doesn't. Passing in the end iterator is undefined behavior.

Unfortunately, you need to write:

auto it = std::find(...); if (it != <the part of ... that specifies the end of the range searched>) {     v.erase(it); } 

Of course, you could define:

template typename<Sequence, Iterator> Iterator my_erase(Sequence &s, Iterator it) {     if (it == s.end()) return it;     return s.erase(it); }  my_erase(v, std::find(v.begin(), v.end(), whatever)); 

c.erase() on an associative container returns void, so to generalize this template to all containers you need some -> decltype action.

like image 174
Steve Jessop Avatar answered Sep 20 '22 08:09

Steve Jessop


Erasing end() (or for that matter, even looking at the target of end()) is undefined behavior. Undefined behavior is allowed to have any behavior, including "just work" on your platform. That doesn't mean that you should be doing it; it's still undefined behavior, and I'll come bite you in the worst ways when you're least expecting it later on.

Depending on what you're doing, you might want to consider set or unordered_set instead of vector here.

like image 20
Billy ONeal Avatar answered Sep 23 '22 08:09

Billy ONeal