为什么 std::set 似乎强制使用 const_iterator?
Why does std::set seem to force the use of a const_iterator?
考虑下面的简单程序,它尝试使用对集合中元素的非常量引用来遍历集合的值:
#include <set>
#include <iostream>
class Int
{
public:
Int(int value) : value_(value) {}
int value() const { return value_; }
bool operator<(const Int& other) const { return value_ < other.value(); }
private:
int value_;
};
int
main(int argc, char** argv) {
std::set<Int> ints;
ints.insert(10);
for (Int& i : ints) {
std::cout << i.value() << std::endl;
}
return 0;
}
编译时,gcc 报错:
test.c: In function ‘int main(int, char**)’:
test.c:18:18: error: invalid initialization of reference of type ‘Int&’ from expression of type ‘const Int’
for (Int& i : ints) {
^
是的,我知道我实际上并不是要修改 for 循环中的元素。但关键是我应该能够获得在循环内使用的非 const 引用,因为集合本身不是 const 限定的。如果我创建一个 setter 函数并在循环中使用它,我会得到同样的错误。
集合就像一张地图,没有值,只有键。由于这些键用于加速集合操作的树,因此它们不能更改。因此所有元素都必须是 const 以防止底层树的约束被破坏。
该行为是设计使然。
给你一个非常量迭代器可能会激发你改变集合中的元素;随后的迭代行为将是未定义的。
请注意,C++ 标准表示 set<T>::iterator
是 const
,因此 C++11 之前的老式方法仍然行不通。
std::set
使用包含的值组成一个快速的数据结构(通常是红黑树)。更改值意味着需要更改整个结构。因此,强制 const
ness,std::set
可防止您将其推入不可使用状态。
In a set, the value of an element also identifies it (the value is
itself the key, of type T), and each value must be unique. The value
of the elements in a set cannot be modified once in the container (the
elements are always const), but they can be inserted or removed from
the container.
考虑下面的简单程序,它尝试使用对集合中元素的非常量引用来遍历集合的值:
#include <set>
#include <iostream>
class Int
{
public:
Int(int value) : value_(value) {}
int value() const { return value_; }
bool operator<(const Int& other) const { return value_ < other.value(); }
private:
int value_;
};
int
main(int argc, char** argv) {
std::set<Int> ints;
ints.insert(10);
for (Int& i : ints) {
std::cout << i.value() << std::endl;
}
return 0;
}
编译时,gcc 报错:
test.c: In function ‘int main(int, char**)’:
test.c:18:18: error: invalid initialization of reference of type ‘Int&’ from expression of type ‘const Int’
for (Int& i : ints) {
^
是的,我知道我实际上并不是要修改 for 循环中的元素。但关键是我应该能够获得在循环内使用的非 const 引用,因为集合本身不是 const 限定的。如果我创建一个 setter 函数并在循环中使用它,我会得到同样的错误。
集合就像一张地图,没有值,只有键。由于这些键用于加速集合操作的树,因此它们不能更改。因此所有元素都必须是 const 以防止底层树的约束被破坏。
该行为是设计使然。
给你一个非常量迭代器可能会激发你改变集合中的元素;随后的迭代行为将是未定义的。
请注意,C++ 标准表示 set<T>::iterator
是 const
,因此 C++11 之前的老式方法仍然行不通。
std::set
使用包含的值组成一个快速的数据结构(通常是红黑树)。更改值意味着需要更改整个结构。因此,强制 const
ness,std::set
可防止您将其推入不可使用状态。
In a set, the value of an element also identifies it (the value is itself the key, of type T), and each value must be unique. The value of the elements in a set cannot be modified once in the container (the elements are always const), but they can be inserted or removed from the container.