为什么std :: set.insert()返回一个非const迭代器,但我无法修改它?

时间:2011-04-12 07:56:35

标签: c++ visual-studio-2010 stl iterator set

考虑以下代码示例:

#include <set>
#include <string>

using namespace std;

set<string> string_set;

void foo(const string& a)
{
    pair<set<string>::iterator, bool> insert_result = string_set.insert(a);

    string& val = *(insert_result.first);
    val += " - inserted";
}

所以,除了正确性之外,例如不检查插入成功等等,这段代码看起来应该允许我在插入后修改字符串,但是编译器(VS2010)禁止将迭代器解除引用到非const字符串(我们是从VS2005迁移而来的,没有任何警告就挥了挥手)。

现在,我知道这应该是禁止的,因为它可能会使字符串不唯一,我很高兴它以这种方式工作,但在现实世界的情况下它不是那么明确,因为我想修改一个不参与等价测试或排序的不可变数据成员。

我想知道的是,编译器如何知道我不允许这样做,以及如何在不参考文档的情况下知道(无论如何都没有提及)?

干杯, 盖

2 个答案:

答案 0 :(得分:24)

因为按照标准,通过修改 不允许set<>::iterator。标准具体 允许set<>::iteratorset<>::const_iterator成为。{1}} 相同的类型。虽然它不要求它们是相同的 类型,它确实需要value_type的{​​{1}} 是set<>::iterator

当然,其原因在于对...的任何修改 值可能会使const的不变量无效。

答案 1 :(得分:3)

来自标准:

23.3.3

  

集合是一种关联   容器,支持唯一键   (每个密钥最多包含一个   价值)并提供快速检索   钥匙本身。班级集   支持双向迭代器。

这也来自标准:
    typedef实现已定义     迭代器;     //见23.1

set :: iterator的真正实现是一个常量迭代器,以保持需求具有唯一键。否则,您可以将set中的值更改为所有相同的值。