为什么允许擦除vector.end()

Why erasing vector.end() is allowed?

本文关键字:vector end 擦除 许擦除 为什么      更新时间:2023-10-16

今天我做了一些代码,看起来像这样:

vec.erase(std::remove_if(vec.begin(), vec.end(), <lambda here>));

当上面的代码不应该擦除任何东西时,也就是说std::remove_if应该返回vec.end(),当我收到我的向量时,我非常惊讶,它的大小减少了一:最后一个元素被擦除了。通过将上面的更改为:解决了问题

vec.erase(std::remove_if(vec.begin(), vec.end(), <lambda here>), vec.end());

但问题仍然存在:如何

vec.erase(vec.end());

做什么工作?这不应该是不明确的行为吗?

编辑:显然,我从一开始就对训练不足行为的理解是错误的,我一直观察到的是UB。谢谢大家回答我的问题。

未定义的行为。特别是,这意味着你可能会看到尺寸减少了一个

有关UB 的更多信息

为什么允许擦除vector.end()?

这是不允许的。vector::erase(const_iterator)的参数必须是向量中的有效可取消引用的迭代器。过去的结束迭代器是有效的,但不能取消引用。

[…]怎么能做任何工作?这不应该是不明确的行为吗?

为什么你认为它不能起作用,是不明确的行为?

你认为不明确的行为意味着什么?

首先,它不是

vec.erase(std::remove_if(<lambda here>), vec.end());

它真的是

vec.erase(std::remove_if(vec.begin(), vec.end(), <lambda here>), vec.end());

这与完全不同

vec.erase(vec.end());

后者,vec.erase(vec.end()),当然是未定义的行为。前者不是。

std::remove_if(vec.begin(), vec.end(), <lambda here>)

这将删除向量中与lambda匹配的值,最重要的是,这将返回新序列的结束值。

vec.erase(first, last);

这将删除向量中从first迭代器值开始的值,以及直到但不包括last迭代器的值。

将两者放在一起,就可以从向量中删除匹配的值,然后相应地缩小向量。