C++ 为什么在取消引用std::set::迭代器时需要const?

C++ 为什么在取消引用std::set::迭代器时需要const?,c++,vector,iterator,stdset,C++,Vector,Iterator,Stdset,我有以下代码: std::set< std::vector<int> > testSet; vector<int> v0 = vector<int>(3); vector<int> v11 = vector<int>(3); v0[0] = 0; v0[1] = 10; v0[2] = 20; std::cout << v0[0] << endl

我有以下代码:

    std::set< std::vector<int> > testSet;
    vector<int> v0 = vector<int>(3);
    vector<int> v11 = vector<int>(3);
    v0[0] = 0;
    v0[1] = 10;
    v0[2] = 20;
    std::cout << v0[0] << endl;
    testSet.insert(v0);
    v0[0] = 1;
    v0[1] = 11;
    v0[2] = 22;
    testSet.insert(v0);
    std::set< std::vector<int> >::iterator it;

    for (it = testSet.begin(); it != testSet.end(); it++) {
        const std::vector<int>& i = (*it); 
        std::cout << i[0] << endl;  
    }
当我改变时:

const std::vector<int>& i = (*it)
致:


它停止工作了。显然,它返回一个常量向量&,但为什么会这样呢?集合包含向量,而不是常量向量。

这是因为实际的测试集声明如下所示:

std::set<std::vector<int>, std::less<std::vector<int>>> testSet;
//                         ~~~~~~~~~~~~~~~~~~~~~~~~~~^
也就是说,值_type本身被用作排序谓词的参数,无论它是std::less还是自定义谓词,它在std::set数据结构中的位置可能取决于插入操作时的原始值。 因此,在不重新排序std::set的情况下更改内容将破坏排序逻辑

标准中还提到了非常量迭代器的常量:

§23.2.4关联容器[关联要求] 关联容器的迭代器属于双向迭代器类别。对于值类型与键类型相同的关联容器,迭代器和常量迭代器都是常量迭代器。未指定迭代器和常量迭代器是否为同一类型。
这是因为您的实际测试集声明如下所示:

std::set<std::vector<int>, std::less<std::vector<int>>> testSet;
//                         ~~~~~~~~~~~~~~~~~~~~~~~~~~^
也就是说,值_type本身被用作排序谓词的参数,无论它是std::less还是自定义谓词,它在std::set数据结构中的位置可能取决于插入操作时的原始值。 因此,在不重新排序std::set的情况下更改内容将破坏排序逻辑

标准中还提到了非常量迭代器的常量:

§23.2.4关联容器[关联要求] 关联容器的迭代器属于双向迭代器类别。对于值类型与键类型相同的关联容器,迭代器和常量迭代器都是常量迭代器。未指定迭代器和常量迭代器是否为同一类型。
我提供了一个矛盾的答案。标准过于武断地说,改变对象将改变顺序。我可以很容易地得到一个对象,该对象本身具有可用于排序的常量数据和与其在集合中的顺序无关的非常量数据。我的对象有一个const std::string m_名称,它被我的自定义比较器用于排序,但有一系列setter用于更改有关它的其他内容。

我提供了一个矛盾的答案。标准过于武断地说,改变对象将改变顺序。我可以很容易地得到一个对象,该对象本身具有可用于排序的常量数据和与其在集合中的顺序无关的非常量数据。我的对象有一个const std::string m_名称,它被我的自定义比较器用于排序,但有一系列setter用于更改有关它的其他内容。

因为对vector的任何更改都会破坏set中的排序。参考中有关于此的信息吗?我看不出来。第一点在第二段中提到:一旦在容器中元素总是常量,那么在成员类型之后,集合中元素的值就不能修改:*注意:集合中的所有迭代器都指向常量元素。原因,为什么一定是这样,在网站上没有详细说明。有什么原因让人们用评论而不是答案来回答吗?@user107986 cppreference链接将是-你链接到cplusplus.com,因为对vector的任何更改都会破坏set中的顺序cppreference上有关于这方面的信息吗?我看不出来。第一点在第二段中提到:一旦在容器中元素总是常量,那么在成员类型之后,集合中元素的值就不能修改:*注意:集合中的所有迭代器都指向常量元素。网站上没有详细说明为什么会这样。人们用评论而不是答案回答有什么原因吗?@user107986 CPPPreference链接是-你链接到cplusplus.com