gpt4 book ai didi

c++ - vector : rend() is being invalidated by erase()

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:08:46 26 4
gpt4 key购买 nike

根据 C++ 规范 (23.2.4.3),vector::erase() 仅使“删除点之后的所有迭代器和引用”无效

因此,当使用 reverse_iterators 传递所有 vector 成员时,当前迭代器上的删除应该不会导致 rend() 成员失效。

此代码将在 G++ 下运行,但会在 Windows (VS2010) 上提供运行时异常:

#include <vector>

using namespace std;

int main()
{
vector<int> x;
x.push_back(1);
x.push_back(2);
x.push_back(3);

//Print
for(vector<int>::const_iterator i = x.begin(); i != x.end(); ++i)
printf("%d\n", *i);

//Delete second node
for(vector<int>::reverse_iterator r = x.rbegin(); r != x.rend(); ++r)
if(*r == 2)
x.erase((r+1).base());

//Print
for(vector<int>::const_iterator i = x.begin(); i != x.end(); ++i)
printf("%d\n", *i);

return 0;
}

错误很有趣:

Expression: vector iterator not decrementable

在第二次运行时在第二个 for 循环的行上给出。减量指的是 reverse_iterator 的内部“当前”迭代器成员,每当 reverse_iterator 递增时它都会递减。

有人能解释一下这种行为吗?

谢谢。

编辑

我认为这段代码示例更好地表明这不是 r 的问题,而是 rend() 的问题:

//Delete second node
for(vector<int>::reverse_iterator r = x.rbegin(); r != x.rend();)
{
vector<int>::reverse_iterator temp = r++;

if(*temp == 2)
x.erase((temp+1).base());
}

删除后进入 for 循环时出现 vector iterators incompatible 错误。

最佳答案

您的程序调用未定义行为。因此,这两种编译器都不正确。

根据标准,std::vector<int>::reverse_iteratorstd::reverse_iterator<std::vector<int>::iterator> 的类型定义. std::reverse_iterator<Iter>的执行指定有一个 protected成员(member)Iter current; ,以及 reverse_iterator 的所有其他成员和函数是根据成员(member)的行为指定的 current .

假设我们有r == reverse_iterator(i) , 其中istd::vector<int> x; 的有效迭代器.这些中的每一个都由标准保证。

r.current == i
(r+1).current == (i-1)
(r+1).base() == (i-1)

调用x.erase((r+1).base()); , i-1 之后的所有迭代器无效。当然,这包括i ,因此也是 r.current .

您的程序接下来尝试评估的是 ++r .此表达式被指定为具有效果 --r.current; .但是因为 r.current已失效,此表达式为未定义行为; ++r也是如此.

关于c++ - vector : rend() is being invalidated by erase(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5236082/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com