c++ - std::map:当元素不可默认构造时创建/替换元素

标签 c++ std stdmap deleted-functions

假设您有一个不可默认构造的类。

class A {
  private:
    int a;
  public:
    A() = delete;
    A(int a0) : a(a0) {}
};

现在,我们有一些 map Int --> A, std::map<int, A> mapping 。假设我们要为某个键 0 创建一个新映射,如果该键存在,我们要替换旧值。对于默认构造类执行此操作的方法是:

mapping[0] = A(4);

这对于 A 类来说会失败,因为operator[] 首先构造 A 的默认实例,然后才会分配 A(4) 的值。 。一般来说(即对于非默认可构造类)执行此操作的一种方法是:

auto it = mapping.find(0);
if (it == mapping.end()) {
  mapping.insert(0, A(4));
}
else {
  it->second = A(4);
}

我的问题是:这真的是(C++)预期的方法吗?我觉得这是不对的;作为一名程序员,我不想为这么少的钱编写这么多代码。但似乎没有简单的解决办法:我查找了常见的 map 方法(insert、emplace、emplace_hint),如果 key 已经存在,那么所有这些方法都不会执行任何操作。

最佳答案

I have looked up common map methods (insert, emplace, emplace_hint) and all of them do nothing if the key is already present.

C++17 已通过 std::map::insert_or_assign 解决了这一点。 :

template <class M>
pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);

If a key equivalent to k already exists in the container, assigns std::forward<M>(obj) to the mapped_type corresponding to the key k. If the key does not exist, inserts the new value as if by insert, constructing it from value_type(k, std::forward<M>(obj)).

这使得

auto it = mapping.find(0);
if (it == mapping.end()) {
  mapping.insert(0, A(4));
}
else {
  it->second = A(4);
}

看起来像

mapping.insert_or_assign(0, A(4));

full program demo

关于c++ - std::map:当元素不可默认构造时创建/替换元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59757248/

相关文章:

c++ - 为什么映射的构造函数允许我们在参数中传递比较器对象?

c++ - 跨多个对象使用 map

c++ - 为什么 char 数组的 alignof 总是 1?

c++ - 实现基于模板的运算符分配函数时出现链接错误

C++ std::stack 遍历

c++ - 为什么 Fmtflags 被指定两次 - 一次作为枚举的一部分,另一个实例作为静态常量变量

c++ - 如何查看 C++ 程序的汇编代码?

c++ - 逗号在数字中的含义

c++ - QThread 与 std::thread

c++ - map.find() 看似随机返回 map.end()