gpt4 book ai didi

c++ - 在使用迭代器和 pop_back 循环时出现单一迭代器错误

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

给出下面的代码(假设它被命名为deque.cpp)

#include <cstdio>
#include <deque>

int main()
{
std::deque<int> d = {1, 2, 3};
for (auto it = d.rbegin(); it != d.rend();) {
printf("it: %d\n", *it);
++it;
d.pop_back();
}
return 0;
}

g++ -std=c++11 -o deque deque.cpp编译,运行良好:

$ ./deque
it: 3
it: 2
it: 1

但是,如果使用 -D_GLIBCXX_DEBUG (g++ -std=c++11 -o deque_debug deque.cpp -D_GLIBCXX_DEBUG 编译,它会出现以下错误:

$ ./deque_debug
it: 3
/usr/include/c++/4.8/debug/safe_iterator.h:171:error: attempt to copy-
construct an iterator from a singular iterator.
...

看起来第二个循环的 ++it 是从单个迭代器构建的。但我认为在第一个循环的++it之后,迭代器指向2,pop_back()不应该使它失效。那为什么会报错呢?

注意:我知道代码可以重写如下:

  while (!d.empty()) {
auto it = d.rbegin();
printf("it: %d\n", *it);
d.pop_back();
}

错误将消失。

但我确实想知道错误代码到底发生了什么。 (这是否意味着反向迭代器实际上并不指向我期望的节点,而是指向它之后的节点?)


更新:@Barry 的回答解决了这个问题。请让我提出一个额外的相关问题:代码

  for (auto it = d.rbegin(); it != d.rend();) {
printf("it: %d\n", *it);
d.pop_back();
++it; // <== moved below pop_back()
}

应该是错误的,其中 ++it 应该在无效的迭代器上运行。但是为什么代码没有报错呢?

最佳答案

这里的问题来自反向迭代器实际上是什么。 reverse iterator的相关关系是:

For a reverse iterator r constructed from an iterator i, the relationship &*r == &*(i-1) is always true (as long as r is dereferenceable); thus a reverse iterator constructed from a one-past-the-end iterator dereferences to the last element in a sequence.

然后我们做 std::deque::pop_back() ,我们使:

Iterators and references to the erased element are invalidated. The past-the-end iterator is also invalidated. Other references and iterators are not affected.

rbegin()end() 构建。在我们第一次递增 it 之后,it 将取消对 2 的引用,但它的底层基础迭代器指向 3 - 那是被删除的元素。所以引用它的迭代器包括你现在高级的反向迭代器。这就是它无效的原因,也是您看到所看到的错误的原因。

反向迭代器很复杂。


您可以将它重新分配给 rbegin(),而不是递增 :

for (auto it = d.rbegin(); it != d.rend();) {
printf("it: %d\n", *it);
d.pop_back();
// 'it' and 'it+1' are both invalidated
it = d.rbegin();
}

关于c++ - 在使用迭代器和 pop_back 循环时出现单一迭代器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37280744/

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