简体   繁体   English

为什么std :: set.insert()返回一个非常量迭代器,而我却不能修改它?

[英]Why does std::set.insert() return a non-const iterator, and yet I cannot modify it?

Consider this code example: 考虑以下代码示例:

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

So, correctness aside, such as not checking for successful insertion and so on, this code looks like it should allow me to amend the string after insertion, but the compiler (VS2010) forbids dereferencing the iterator to a non-const string (we're migrating from VS2005 which waved this through without a warning). 因此,除了正确性外,例如不检查是否成功插入等等,这段代码看起来应该允许我在插入后修改字符串,但是编译器(VS2010)禁止将迭代器引用为非const字符串(从VS2005重新迁移,这在没有警告的情况下进行了摇晃)。

Now, I know this should be forbidden since it may make the string non-unique, and I'm kind of glad it works this way, but in the real world case it's not quite so clear cut as that, as I want to amend a non-mutable data member that doesn't participate in equivalence testing or ordering. 现在,我知道应该禁止这样做,因为它可能会使字符串变得不唯一,并且我很高兴以这种方式工作,但是在现实世界中,它并没有那么清晰,因为我想修改不参与等效性测试或排序的非可变数据成员。

What I want to know is, how does the compiler KNOW I'm not allowed to do this, and how do I know without reference to the documentation (which doesn't mention this anyway)? 我想知道的是,编译器如何知道我不允许这样做,以及如何在不参考文档的情况下知道(反正也没有提及)?

Cheers, Guy 干杯,家伙

Because according to the standard, modifications through a set<>::iterator are not allowed. 因为根据标准,不允许通过set<>::iterator进行修改。 The standard specifically allows set<>::iterator and set<>::const_iterator to be the same type. 该标准特别允许set<>::iteratorset<>::const_iterator为相同类型。 And although it doesn't require them to be the same type, it does require the value_type of set<>::iterator to be const . 尽管不需要它们是相同的类型,但它确实需要set<>::iteratorvalue_typeconst

The reason for this, of course, is that any modifications to the value could invalidate the invariants of std::set<> . 当然,这样做的原因是对该值的任何修改都可能使std::set<>的不变式失效。

From the standard : 从标准:

23.3.3 23.3.3

A set is a kind of associative container that supports unique keys (contains at most one of each key value) and provides for fast retrieval of the keys themselves. 集合是一种关联容器,它支持唯一键(每个键值最多包含一个)并提供键本身的快速检索。 Class set supports bidirectional iterators. 类集支持双向迭代器。

This is also from the standard : 这也来自标准:
typedef implementation defined iterator; typedef实现定义的迭代器; // See 23.1 //参见23.1

The real implementation of set::iterator is a constant iterator in order to keep the requirement to have unique keys. set :: iterator的实际实现是一个常量迭代器,以保持具有唯一键的要求。 Otherwise you could change the values in set to all the same values. 否则,您可以将set中的值更改为所有相同的值。

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

相关问题 为什么std ::(multi)set提供非const迭代器方法 - Why does std::(multi)set provide non const iterator methods 为什么我不能在 std::set 中的元素上调用非常量成员函数? - Why can't I call a non-const member function on an element in an std::set? 为什么运算符 ++ 返回一个非常量值? - Why does operator ++ return a non-const value? 为什么getenv()返回一个非常量字符串 - Why does getenv() return a non-const string std::set.insert c++ 的问题 - Troubles with std::set.insert c++ 列表的迭代器可以返回非常量引用吗? - Can list's iterator return a non-const reference? 为什么“std :: begin()”在这种情况下总是返回“const_iterator”? - Why does “std::begin()” always return “const_iterator” in such a case? 了解C ++中对迭代器的const引用和非const引用。 为什么在打印功能中不能使用对迭代器的非常量引用? - Understanding const references and non-const references to iterators in C++. Why can't I use a non-const reference to iterator in the print function? 为什么 `std::priority_queue::top()` 不能返回非常量引用? - Why can't `std::priority_queue::top()` return a non-const reference? 为什么std :: num_put通过非常量引用采用ios_base参数? - Why does std::num_put take the ios_base parameter by non-const reference?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM