Does it works correctly (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
Does it works correctly (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
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.
position
as "Iterator pointing to a single element". An end iterator does not point to a single element. –
Latrice end() - 1
instead of "vector end". –
Talos 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.
{ auto it = v.find(x); if (it != x.end()) { v.erase(it); } }
–
Hardcastle end-1
will work if and only if the container is not empty. (Same as pop_back
) –
Unstop Have you tried this?
v.erase(remove_if(v.begin(), v.end(), (<your criteria>)), v.end());
remove_if
, I guess –
Paley vec.erase(vec.end())
clearly isn't –
Cassicassia vec.erase(vec.end(), vec.end());
be ok when vec.erase(vec.end())
isn't –
Cassicassia vec.erase(vec.end(), vec.end())
erases a range (that happens to be zero-sized and so refers to zero items). vec.erase(vec.end())
attempts to erase an item that doesn't exist. –
Never Since C++ 17, if statements can have an init statement, so erasing an element that may not be present can be simplified. As a bonus, the variable used for the iterator will not be visible outside the scope of the if statement.
if (auto it = std::find(v.begin(), v.end(), value); it != v.end()) v.erase(it);
In addition, std::ranges::find
(or std::ranges::find_if
) can be used since C++ 20, which don't require passing in begin()
and end()
iterators.
if (auto it = std::ranges::find(v, value); it != v.end()) v.erase(it);
The above solutions remove the first occurrence of value
if it exists. To remove all occurrences of a value, std::erase
from <vector>
may be used since C++ 20.
std::erase(v, value);
© 2022 - 2025 — McMap. All rights reserved.