我有以下代码:
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
向量。
答案 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]
关联容器的
- 醇>
iterator
属于双向迭代器类别。对于值类型与键类型相同的关联容器,iterator
和const_iterator
都是常量迭代器。未指定iterator
和const_iterator
是否为同一类型。
答案 1 :(得分:1)
我提供了一个矛盾的答案。标准过于放肆地说改变对象会改变顺序。我可以轻松地拥有一个对象,该对象本身具有可用于排序的常量数据和非常数数据,这些数据与集合中的顺序无关。我的对象有一个const std :: string m_name,我的自定义比较器使用它来进行排序,但是有一大堆setter用于更改其他东西。