擦除矢量::从矢量结束

Ria*_*iaD 33 c++ iterator vector erase language-lawyer

我使用时它是否正常(无效)

 vector<T> v;
 v.erase(v.end());
Run Code Online (Sandbox Code Playgroud)

我想用类似的东西

 v.erase(std::find(...));
Run Code Online (Sandbox Code Playgroud)

我应该ifv.end()还是不是?
C++.comCPPreference上没有关于它的信息

Ste*_*sop 27

该标准并未完全拼写出来,但v.erase(q)定义为"删除q"中指向的元素[sequence.reqmts].这意味着q必须实际指向一个元素,而结束迭代器不会.传递到最后迭代器是未定义的行为.

不幸的是,你需要写:

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

当然,您可以定义:

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));
Run Code Online (Sandbox Code Playgroud)

c.erase()在关联容器上返回void,因此要将此模板概括为您需要一些-> decltype操作的所有容器.


Bil*_*eal 24

擦除end()(或者就此而言,甚至查看目标end())是未定义的行为.允许未定义的行为具有任何行为,包括在您的平台上"正常工作".这并不意味着你应该这样做; 它仍然是未定义的行为,当你最不期待它时,我会以最糟糕的方式咬你.

根据您正在做的事情,您可能需要考虑setunordered_set代替vector此处.

  • @Gaffi:当且仅当容器不为空时,`end-1`才会起作用.(与`pop_back`相同) (2认同)

Gaf*_*ffi 5

你试过这个吗?

v.erase(remove_if(v.begin(), v.end(), (<your criteria>)), v.end());
Run Code Online (Sandbox Code Playgroud)

  • 我不知道为什么这个被低估了(除了可能已编辑的初始答案).现在的代码是正确的. (4认同)
  • @DavidRodríguez-dribeas:正如最初发布的那样,这是不正确的.现在它已被编辑为正确,我删除了我的downvote. (3认同)