【问题标题】:Why const is required when dereferencing std::set<T>::iterator?为什么取消引用 std::set<T>::iterator 时需要 const?
【发布时间】:2014-09-19 10:28:20
【问题描述】:

我有以下代码:

    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&lt;int&gt;&amp;,但为什么会这样呢?该集合包含向量,而不是 const 向量。

【问题讨论】:

  • 因为对向量的任何更改都会破坏集合内的顺序
  • cppreference 上有没有关于这个的信息? cplusplus.com/reference/set/set我没看到。
  • 第一次提到是在第二段:The value of the elements in a set cannot be modified once in the container (the elements are always const) 然后在会员类型之后:*Note: All iterators in a set point to const elements. 原因,为什么一定是这样,网站上没有详细说明。
  • 人们有什么理由用 cmets 而不是 answers 回答?
  • @user107986 cppreference 链接将是 en.cppreference.com/w/cpp/container/set -- 你链接到 cplusplus.com

标签: c++ vector iterator stdset


【解决方案1】:

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

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

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

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

§ 23.2.4 关联容器[associative.reqmts]

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-30
      • 2021-06-02
      • 2010-12-06
      • 2015-02-27
      • 1970-01-01
      • 1970-01-01
      • 2021-08-12
      相关资源
      最近更新 更多