vector :: iterator和set :: iterator之间的主要区别

时间:2013-01-11 09:40:49

标签: c++ stl vector iterator set

我在C ++ \ STL测试论文中注意到了这样一个问题。

有什么想法吗?

可能这与事实有某种联系,即在集合中删除元素会导致“vector after deleted after iterator in vector”中的失效,只有集合中已删除的迭代器?

2 个答案:

答案 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需要一个完全不同的时间(需要至少是线性循环)