Why does insert invalidate the std::set reverse iterator(为什么插入使 std::set 反向迭代器无效)
问题描述
我的理解是关联容器的迭代器在插入或擦除期间不会失效(除非迭代器指向的节点被擦除).但是在下面的程序中插入似乎使迭代器无效.是不是我的理解错了?
My understanding is the iterators of associative containers are not invalidated during insert or erase (unless the node pointed by iterator is erased). But in the below program the insert seems to invalidate the iterator. Is my understanding wrong?
typedef std::set<unsigned int> myset_t;
int main(int argc, char **argv)
{
myset_t rs;
myset_t::reverse_iterator rit;
myset_t::reverse_iterator srit;
int ii = 500;
rs.insert(10);
rs.insert(11);
rs.insert(12);
rs.insert(13);
rs.insert(14);
rs.insert(100000);
rs.insert(102000);
rs.insert(103000);
rit = rs.rbegin();
while(rit != rs.rend()) {
srit = rit;
if (*rit < 100000) {
cout << "bailing here " << *rit << endl;
return 0;
}
rit++;
cout << "Before erase " << *rit << endl;
rs.erase(*srit);
cout << "Before insert " << *rit << endl;
rs.insert(ii);
cout << "After insert " << *rit << endl;
ii++;
}
cout << "Out of loop" << endl;
}
===
The output is
Before erase 102000
Before insert 102000
After insert 14
bailing here 14
=====
推荐答案
标准容器迭代器的承诺行为不适用于该容器的反向迭代器.
The promised behavior for iterators of a standard container does not hold for reverse iterators of that container.
反向迭代器实际上将正常(向前移动的)迭代器存储为成员,它在取消引用时位于反向迭代器所引用的元素之后.然后,当您取消引用反向迭代器时,本质上它会递减这个存储的普通迭代器的副本并取消引用它.所以这是一个问题:
A reverse iterator actually stores, as a member, the normal (forward moving) iterator which comes after the element to which the reverse iterator refers when dereferenced. Then when you dereference the reverse iterator, essentially it decrements a copy of this stored normal iterator and dereferences that. So this is a problem:
rit = rs.rbegin(); // rit stores rs.end()
srit = rit; // srit also stores rs.end()
rit++; // rit stores a normal iterator pointing to the last element
rs.erase(*srit); // this deletes the last element, invalidating the normal
// iterator which is stored in rit. Funnily enough, the
// one stored in srit remains valid, but now *srit is a
// different value
反向迭代器的行为是这样的,因为没有before begin"迭代器.如果他们将迭代器存储到他们实际引用的元素中,rs.rend()
会存储什么?我确信有办法解决这个问题,但我想他们需要标准委员会不愿意做出的妥协.或者他们可能从未考虑过这个问题,或者认为它不够重要.
Reverse iterators behave this way because there is no "before begin" iterator. If they stored the iterator to the element to which they actually refer, what would rs.rend()
store? I'm sure there are ways around this, but I guess they required compromises which the standards committee was not willing to make. Or perhaps they never considered this problem, or didn't consider it significant enough.
这篇关于为什么插入使 std::set 反向迭代器无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:为什么插入使 std::set 反向迭代器无效
基础教程推荐
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- Windows Media Foundation 录制音频 2021-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- 从 std::cin 读取密码 2021-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01