为什么允许擦除 vector.end()?
Why erasing vector.end() is allowed?
今天我做了一些代码,看起来像这样:
vec.erase(std::remove_if(vec.begin(), vec.end(), <lambda here>));
当上面的代码不应该擦除任何东西时,这意味着 std::remove_if 应该 return vec.end(),当我收到尺寸减小了 1 的矢量时,我感到非常惊讶: 最后一个元素被删除。通过将上面更改为:
来解决问题
vec.erase(std::remove_if(vec.begin(), vec.end(), <lambda here>), vec.end());
但问题仍然存在:如何才能
vec.erase(vec.end());
有工作吗?不应该是未定义的行为吗?
编辑: 显然我对欠定义行为的理解从一开始就是错误的,我观察到的一直是 UB。谢谢大家回答我的问题。
它是未定义的行为。
特别是,这意味着您可能会看到尺寸减小了一个
More on UB
Why erasing vector.end() is allowed?
这是不允许的。 vector::erase(const_iterator)
的参数必须是向量中的 有效可取消引用 迭代器。尾后迭代器有效但不可取消引用。
how can [...] do any work? Shouldn't it be undefined behaviour?
为什么你认为它不能工作并且是未定义的行为?
你认为未定义的行为是什么意思?
首先,不是
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 匹配的值,并且——最重要的是——这 returns 新序列的结束值。
vec.erase(first, last);
这将删除向量中的值,从 first
迭代器值开始,直到但不包括 last
迭代器值。
将两者放在一起,就是从向量中删除匹配值,然后相应地缩小向量。
今天我做了一些代码,看起来像这样:
vec.erase(std::remove_if(vec.begin(), vec.end(), <lambda here>));
当上面的代码不应该擦除任何东西时,这意味着 std::remove_if 应该 return vec.end(),当我收到尺寸减小了 1 的矢量时,我感到非常惊讶: 最后一个元素被删除。通过将上面更改为:
来解决问题vec.erase(std::remove_if(vec.begin(), vec.end(), <lambda here>), vec.end());
但问题仍然存在:如何才能
vec.erase(vec.end());
有工作吗?不应该是未定义的行为吗?
编辑: 显然我对欠定义行为的理解从一开始就是错误的,我观察到的一直是 UB。谢谢大家回答我的问题。
它是未定义的行为。 特别是,这意味着您可能会看到尺寸减小了一个
More on UB
Why erasing vector.end() is allowed?
这是不允许的。 vector::erase(const_iterator)
的参数必须是向量中的 有效可取消引用 迭代器。尾后迭代器有效但不可取消引用。
how can [...] do any work? Shouldn't it be undefined behaviour?
为什么你认为它不能工作并且是未定义的行为?
你认为未定义的行为是什么意思?
首先,不是
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 匹配的值,并且——最重要的是——这 returns 新序列的结束值。
vec.erase(first, last);
这将删除向量中的值,从 first
迭代器值开始,直到但不包括 last
迭代器值。
将两者放在一起,就是从向量中删除匹配值,然后相应地缩小向量。