如何将具有常量字段的对象添加到 std::map?

How to add to std::map an object with constant field?

假设我有以下代码:

#include <string>
#include <map>

struct A {
    const int value;
    A(int value) : value{value} {}
};

int main() {
    A a{3};
    std::map<std::string, A> myMap;
    myMap["Hello"] = a; // Error: Copy assignment operator of 'A' is implicitly deleted because 
                        //        field 'value' is of const-qualified type 'const int'.
    return 0;
}

嗯,我理解错误。但是我不能为这种类型的结构覆盖 operator=,因为它有 const int value 字段。那我该怎么办?

这里的评论者提出了不同的解决方案,各有利弊。让我清除我需要的行为。

  1. const int value永远不变。没有修改它的技巧或技巧。
  2. 如果键不存在于 map 中,则赋值意味着“将 [key, value] 对添加到映射中”。但如果键存在,则替换值。
  3. 没有默认创建 A 个对象。使用映射中不存在的键访问 map 应该会引发错误或中止或其他问题。但是,不允许为不存在的键 创建默认 'A' 对象

如果我理解所有提出的解决方案,我能做的最好的事情就是围绕 std::map 创建一些包装器。你怎么看?

使用map::emplace就地构造A

myMap.emplace("Hello", 3);

Demo.

If the key doesn't exist in a map, then assignment means "add pair [key, value] to the map". But if the key exists, then replace the value.

正如@Serge Ballesta 评论的那样,当密钥已经存在时,您需要从地图中删除该节点并放置一个新节点:

const char* key = "Hello";
const int value = 3;
const auto it = myMap.find(key);
if (it != myMap.end())
  myMap.erase(it);
myMap.emplace(key, value);

struct A作为map的值,需要一个构造函数和一个operator=():

struct A {
  const int32_t value;
  A(): value(0) {}
  A(int32_t value) : value(value) {}

  A& operator=(const A& other) {
    // this change the value, if don't want change it, ignore this.
    // this is an undefined behavior. ignore this.
    // const_cast<int32_t&>(value) = other.value;
    return *this;
  }
};