为什么在解除引用std :: set <t> :: iterator?</t>时需要const

时间:2014-09-19 10:28:20

标签: 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;
    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)会返回const vector<int>&,但为什么会这样呢?该集合包含向量,而不是const向量。

2 个答案:

答案 0 :(得分: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的情况下更改内容会破坏排序逻辑。

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

  

§23.2.4关联容器[associative.reqmts]

     
      关联容器的
  1. iterator属于双向迭代器类别。对于值类型与键类型相同的关联容器,iteratorconst_iterator都是常量迭代器。未指定iteratorconst_iterator是否为同一类型。
  2.   

答案 1 :(得分:1)

我提供了一个矛盾的答案。标准过于放肆地说改变对象会改变顺序。我可以轻松地拥有一个对象,该对象本身具有可用于排序的常量数据和非常数数据,这些数据与集合中的顺序无关。我的对象有一个const std :: string m_name,我的自定义比较器使用它来进行排序,但是有一大堆setter用于更改其他东西。