问题
Today I was doing a bit of code, which looked something like this:
vec.erase(std::remove_if(vec.begin(), vec.end(), <lambda here>));
When above code was not supposed to erase anything, meaning that std::remove_if should return vec.end(), I was very surprised when i received my vector with size decreased by one: last element was erased. Problem was fixed by changing above to:
vec.erase(std::remove_if(vec.begin(), vec.end(), <lambda here>), vec.end());
But still question remains: how can
vec.erase(vec.end());
do any work? Shouldn't it be undefined behaviour?
Edit: Apparently my understanding of underfined behaviour was wrong from the beginning and what i observed was UB all along. Thank you everyone for answering my question.
回答1:
It is undefined behaviour. In particular, it means that you may see size decreased by one
More on UB
回答2:
Why erasing vector.end() is allowed?
It isn't allowed. The argument to vector::erase(const_iterator)
must be a valid dereferenceable iterator into the vector. The past-the-end iterator is valid but not dereferenceable.
how can [...] do any work? Shouldn't it be undefined behaviour?
Why do you think it can't do work and be undefined behaviour?
What do you think undefined behaviour means?
回答3:
First of all, it's not
vec.erase(std::remove_if(<lambda here>), vec.end());
It is really
vec.erase(std::remove_if(vec.begin(), vec.end(), <lambda here>), vec.end());
Which is something completely different from
vec.erase(vec.end());
The latter, vec.erase(vec.end())
, is certainly undefined behavior. The former is not.
std::remove_if(vec.begin(), vec.end(), <lambda here>)
This removes the values in the vector that are matched by the lambda, and -- most importantly -- this returns the ending value of the new sequence.
vec.erase(first, last);
This removes the values in the vector starting from the first
iterator value, and up to but not including the last
iterator value.
Put the two together, and you are removing matching values from the vector, and then shrinking the vector accordingly.
来源:https://stackoverflow.com/questions/34415407/why-erasing-vector-end-is-allowed