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

Евг*_*лов 3 c++ stl stdmap

假设我有以下代码:

#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;
}
Run Code Online (Sandbox Code Playgroud)

好吧,我理解这个错误。但我无法覆盖operator=这种类型的结构,因为它有const int value字段。所以我该怎么做?

这里的评论者提出了不同的解决方案,各有优缺点。让我澄清我需要的行为。

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

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

康桓瑋*_*康桓瑋 8

用于就地map::emplace构建:A

myMap.emplace("Hello", 3);
Run Code Online (Sandbox Code Playgroud)

演示。

如果映射中不存在该键,则赋值意味着“将 [键,值] 对添加到映射中”。但如果键存在,则替换该值。

正如 @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);
Run Code Online (Sandbox Code Playgroud)

  • 这确实是正确的方法,但是`operator =`和`emplace`之间有很大的区别。如果键已经存在,`operator =` 将更改现有值,而 emplace 不会。您必须删除先前的值(如果存在)以保持“operator =”行为 (5认同)