我从 std::set 得到 const_iterator 而不是迭代器

I get const_iterator instead of iterator from std::set

我有以下代码根本无法编译。 它说我不能将 const Node 转换为 Node&Node 不是 const 也不是 A 的方法引用 const this 也不是 std::set 是常量。

我哪里错了?

#include <set>
#include <string>

struct Node
{
    std::string name;
};

struct NodeNameComparator
{
    using is_transparent = void;
    bool operator()(const Node &a, const std::string &b) const { return a.name < b; }
    bool operator()(const std::string &a, const Node &b) const { return a < b.name; }
    bool operator()(const Node &a, const Node &b) const { return a.name < b.name; }
};


struct A
{
    std::set<Node, NodeNameComparator> nodeset;
    Node &add_or_get_node(const std::string &name)
    {
        std::set<Node, NodeNameComparator>::iterator it = nodeset.template find(name);
        // IT WORKS BUT IT IS A WORKAROUND.
        //return it == nodeset.end() ? const_cast<Node&>(*(nodeset.insert(*new Node{name}).first)) : const_cast<Node&>(*it);
        //ERROR!!!
        return it == nodeset.end() ? *(nodeset.insert(*new Node{name}).first) : *it;
    };
};

int main() { return 0; }

std::set 不仅仅是一组元素,它是一组经过排序的唯一元素。 std::set 的元素在设计上是不可变的,因此您不能通过修改其元素来破坏 std::set 不变性。这就是为什么 std::set::iteratorstd::set::const_iterator 都是常量迭代器的原因。

std::set 上的 Cppreference reads:

Member type       Definition 

iterator          Constant LegacyBidirectionalIterator
const_iterator    Constant LegacyBidirectionalIterator

另见 this LWG issue

Keys in an associative container are immutable. ... For associative containers where the value type is the same as the key type, both iterator and const_iterator are constant iterators.

Rationale: ... if elements were mutable, there would be no compile-time way to detect of a simple user oversight which caused ordering to be modified. There was a report that this had actually happened in practice, and had been painful to diagnose. If users need to modify elements, it is possible to use mutable members or const_cast.