Erasing vector::end from vector

2019-01-19 09:38发布

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

3条回答
Anthone
2楼-- · 2019-01-19 10:10

Have you tried this?

v.erase(remove_if(v.begin(), v.end(), (<your criteria>)), v.end());
查看更多
男人必须洒脱
3楼-- · 2019-01-19 10:19

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.

查看更多
Luminary・发光体
4楼-- · 2019-01-19 10:22

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.

查看更多
登录 后发表回答