关于C ++ Iterator invalidation rules的最受欢迎的帖子声称不清楚过去的结束迭代器(即end()
,cend()
,rend()
返回的迭代器,和crend()
)根据与普通迭代器相同的规则无效,这些迭代器指向容器中的元素。这些针对2003年和2011年C ++的声明,推迟到讨论End iterator invalidation rules的帖子,其中接受的答案表明2003标准在这个问题上是模棱两可的。这个结论基于23.1 / 10中的注释(在swap()
的上下文中)似乎意味着当规范没有明确提到过去的迭代器失效时,它们可能会失效。
对该帖子的问题的评论(由mike-seymour提出)表明C ++ 11在这个问题上是明确的,在deque
s的情况下。我的问题是关于所有容器:
不同地说,
答案 0 :(得分:11)
我的问题是关于所有容器:
- 在C ++ 11中,是否有任何容器操作可能使过去的迭代器无效,并且这种行为在这里是不明确的 语言规范?
我不确定你对“语言规范中这种行为模糊不清”的意思,但肯定有一些操作会使过去的操作符无效(比如插入std::vector
或{{1 }})。
不同地说,
- 执行容器操作后,我是否可以信任过去的迭代器的有效性,但不会说它可能会失效 过去的结束迭代器?
您可以像任何其他迭代器一样信任过去的迭代器:任何不会(可能)使迭代器失效的操作都不会使它们失效。除了标准运行错误的可能性之外,所有操作都没有说它们(可能)使运营商无效。
答案 1 :(得分:2)
如果标准说操作不会使迭代器无效,那么你应该能够信任它。其他任何东西都应该被视为标准库实现中的错误。
答案 2 :(得分:0)
至少在GCC结束时,迭代器会因为std :: map:
而失效#include <set>
#include <stdlib.h>
#include <assert.h>
int main() {
std::set<int> a;
a.insert(1);
std::set<int>::reverse_iterator rit(a.rbegin());
++rit;
assert(rit==a.rend());
a.erase(a.begin());
assert(a.rend()==rit); // FAIL
}