1

我有以下代码:

    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::vector<int>& i = (*it)

它停止工作。显然(*it)返回 a const vector<int>&,但为什么会这样呢?该集合包含向量,而不是const向量。

4

2 回答 2

3

这是因为您的实际testSet声明如下所示:

std::set<std::vector<int>, std::less<std::vector<int>>> testSet;
//                         ~~~~~~~~~~~~~~~~~~~~~~~~~~^

也就是说,它value_type本身被用作排序谓词的参数(无论它是std::less<T>还是自定义谓词),它在std::set数据结构(可能是RB-tree)中的位置取决于它的原始值(在insert操作时)。因此,在不重新排序的情况下更改内容std::set会破坏排序逻辑。

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

§ 23.2.4 关联容器[associative.reqmts]

  1. iterator关联容器属于双向迭代器类别。对于值类型与键类型相同的关联容器,两者iterator都是const_iterator常量迭代器。未指定iteratorconst_iterator是否为同一类型。
于 2014-09-19T11:01:50.973 回答
1

我提供了一个矛盾的答案。标准说改变对象就会改变顺序,这太冒昧了。我可以很容易地拥有一个对象,该对象本身具有可用于排序的常量数据和与其在集合中的顺序没有任何关系的非常量数据。我的对象有一个 const std::string m_name ,我的自定义比较器使用它来进行排序,但有一大堆设置器用于更改它的其他内容。

于 2016-05-05T06:35:39.743 回答