简体   繁体   English

为什么取消引用std :: set时需要const <T> ::迭代者?

[英]Why const is required when dereferencing std::set<T>::iterator?

I have the following code: 我有以下代码:

    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;  
    }

When I change: 当我改变时:

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

to: 至:

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

it stops working. 它停止工作。 Apparently (*it) returns a const vector<int>& , but why is it the case? 显然(*it)返回const vector<int>& ,但是为什么会这样呢? The set contains vectors, not const vectors. 该集合包含向量,而不是const向量。

This is because your actual testSet declaration looks as follows: 这是因为您的实际testSet声明如下所示:

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

That is, the value_type itself is used as the argument for ordering predicate (no matter if it is std::less<T> or a custom one), and its location within std::set data structure (possibly RB-tree) depends on its original value (at the time of insert operation). 也就是说, value_type本身用作排序谓词的参数(无论它是std::less<T>还是自定义的),其在std::set数据结构(可能是RB树)中的位置取决于其原始值(在insert操作时)。 Thus, changing the content without reordering the std::set would break the ordering logic. 因此,在不重新排序std::set情况下更改内容将破坏排序逻辑。

The constness of non-const iterator is also mentioned in the standard: 标准中还提到了非常量迭代器的常量性:

§ 23.2.4 Associative containers [associative.reqmts] 第23.2.4条关联容器[associative.reqmts]

  1. iterator of an associative container is of the bidirectional iterator category. iterator关联容器的是双向迭代类。 For associative containers where the value type is the same as the key type, both iterator and const_iterator are constant iterators. 对于值类型与键类型相同的关联容器, iteratorconst_iterator均为常量迭代器。 It is unspecified whether or not iterator and const_iterator are the same type. 不确定iteratorconst_iterator是否为同一类型。

I am providing a contradictory answer. 我提供一个矛盾的答案。 The standard is overly presumptuous in saying that changing the object will change the order. 该标准过于冒昧地说改变对象将改变顺序。 I can easily have an object that itself has constant data that can be used for ordering AND non-constant data that doesn't have anything to do with its order within the set. 我可以很容易地得到一个对象,该对象本身具有可用于排序的常量数据,以及与集合中的顺序无关的非常量数据。 My objects have a const std::string m_name that is used by my custom comparator for ordering, but has a whole slew of setters for changing other things about it. 我的对象有一个const std :: string m_name,我的自定义比较器使用它来进行排序,但是有大量的setter用于更改其他内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM