将“const ...”作为“this”参数传递会丢弃限定符

问题描述

我被卡住了。当尝试通过迭代器向结构内的字符串向量添加新元素时,我收到关于 const 限定符的错误

error: passing ‘const std::vector<std::__cxx11::basic_string<char> >’ as ‘this’ argument discards qualifiers [-fpermissive]
  175 |  p->children.push_back("New child");

代码

typedef struct Concept_tree
{ 
    string id;
    string name; 
    std::vector<string> children; 

    bool operator==(const Concept_tree &ct2)
    {
        return (id == ct2.id);
    } 

    Concept_tree()                                           { };
    Concept_tree(string id):              id(id)             { };
    Concept_tree(string id,string term): id(id),name(term) { };
} 
Concept_tree;


namespace std 
{
    template<>
    struct hash<Concept_tree> 
    {
       size_t operator()(const Concept_tree &ct) const
       {
          return std::hash<string>()(ct.id);
       }
    };
}

...

std::unordered_set<Concept_tree> ct_uset; 

...

string test = "id00001";

auto p = ct_uset.find(test);

p->children.push_back("New child");

我了解错误的原因,但无法推断出其确切位置。是不是构造函数实现不当?有人可以帮忙吗?

解决方法

您从 p 获得了迭代器 unordered_setunordered_set 的内容是不可变的(以避免违反不变量),并且返回的迭代器是元素的 const 视图以确保这一点。

您可以将 children 标记为 mutable,这样即使 Concept_treeconst 也可以对其进行变异(因为它不是等式/哈希计算的一部分,这可能是好的)。但这将使 children 变异成为可能,即使您希望 Concept_tree 在逻辑上是常量。为避免这种情况,您可以使用 unordered_map 映射只是id(不可变键)映射到实际的 Concept_tree(可变值)对象。

旁注:您可能希望将您的 operator== 标记为 const,因此 this 是 const,或者使其成为一个非成员函数,每个 {{3} }.