考虑下面的简单程序,它尝试使用对其中元素的NON-const引用来遍历集合的值:
#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;
}
Run Code Online (Sandbox Code Playgroud)
编译时,我从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) {
^
Run Code Online (Sandbox Code Playgroud)
是的,我知道我实际上并没有尝试修改for循环中的元素.但重点是我应该能够在循环内部使用非const引用,因为set本身不是const限定的.如果我创建一个setter函数并在循环中使用它,我会得到相同的错误.
nat*_*ate 44
集合就像没有值的地图,只有键.由于这些键用于加速集合操作的树,因此它们无法更改.因此,所有元素必须是const,以防止底层树的约束被破坏.
lis*_*rus 10
std::set使用包含的值来形成快速数据结构(通常是红黑树).更改值意味着需要更改整个结构.因此,强迫const,std::set阻止您将其推入不可用状态.
该行为是设计使然。
给您一个非常量迭代器可能会启发您更改集合中的元素。随后的迭代行为将是不确定的。
需要注意的是C ++标准说,set<T>::iterator是const这样的老式前C ++ 11的方式仍然是行不通的。
| 归档时间: |
|
| 查看次数: |
3211 次 |
| 最近记录: |