我在C ++ \ STL测试论文中注意到了这样一个问题。
有什么想法吗?
可能这与事实有某种联系,即在集合中删除元素会导致“vector after deleted after iterator in vector”中的失效,只有集合中已删除的迭代器?
答案 0 :(得分:2)
set::iterator
引用的对象是const
,因为不允许更改set
中的条目值(并且允许更改价值可能会打破秩序)。对于vector::iterator
,情况并非如此。
例如:
#include <vector>
#include <set>
int main()
{
std::set<int> s;
std::vector<int> v;
*v.begin() = 4;
*s.begin() = 4; // Line 10.
return 0;
}
MSVC ++编译器发出:
main.cpp(10):错误C3892:'std :: _ Tree&lt; _Traits&gt; :: begin':你不能分配给const的变量
g ++编译器发出:
错误:只读位置的分配's.std :: set&lt; _Key,_Compare,_Alloc&gt; ::以_Key = int开头,_Compare = std :: less,_Alloc = std :: allocator.std :: _Rb_tree_const_iterator&lt; _Tp&gt; :: operator * with _Tp = int'
答案 1 :(得分:2)
差异与容器的不同性质有关,而不是与迭代器本身有关。
一个方面涉及这些容器的“已排序/未排序”性质:您无法修改位于已排序容器内的元素,因为它会危及订单。
另一方面涉及“紧凑/扩展”存储机制:向量中的元素一起存储在单个分配块中,集合(或列表)中的元素被单独存储。结果,向量中的插入/删除导致元素位移的改变。在set或list中插入/删除只会导致重新链接,所有现有元素都保持其位置(因此不会使引用它们的迭代器无效)
与存储相关的另一个方面是,vector :: iterator是“随机访问”:++ i,i + = 3,i + = 100需要相同的时间,因为位移可以算术计算。在集合(和“链接容器”)迭代器只是“双向”:++ i和--i是立即计算,但i + = 5或i + = 100需要一个完全不同的时间(需要至少是线性循环)