c++ - 无法使用 std::map::emplace 插入没有复制构造函数的类的对象

标签 c++ c++14 copy-constructor stdmap

我正在尝试编译以下代码:

#include <map>
#include <condition_variable>

class MyClass
{
public:
    MyClass(): m_cv() {}
    std::condition_variable m_cv; //just to illustrate that a copy constructor is not obvious to write
};

int main()
{
    std::map<std::string,MyClass> testmap;
    testmap.emplace("key",MyClass());
}

编译在最后一行(emplace 方法调用)失败,并出现一个很长的错误,如下所示:

error: no matching function for call to ‘std::pair, MyClass>::pair(const char [4], MyClass)

通过反复试验,我了解到错误来自于 MyClass 缺少复制构造函数。如果我添加一个,或者如果我用基本类型(例如 int)替换条件变量属性,错误就会消失。但是我不确定我的分析,最重要的是,我不明白为什么这里需要 MyClass 的复制构造函数。

所以我的问题是双重的:

  1. 为什么需要复制构造函数?
  2. 如何重写代码以便不需要复制构造函数(由于类的复杂性,编写起来有点棘手,为简洁起见,此处省略)?

最佳答案

在 C++17 中:

testmap.try_emplace("key");

在 C++14 或更早版本中:

testmap.emplace(std::piecewise_construct, std::forward_as_tuple("key"), std::tuple<>{});

您的代码构造 MyClass 两次:一次手动执行 (MyClass()),第二次 std::map在内部执行(在您的情况下,它尝试调用复制构造函数)。

第二个构造函数调用不会去任何地方,但您可以更改它接收的参数(如果有)。因此,您必须删除第一个调用,并将第二个调用更改为不接收参数,而不是 const MyClass &

.emplace() 的参数直接转到 the constructor of std::pair 。如果您检查构造函数,会发现唯一可以默认构造第二个元素(不包括该对自己的默认构造函数)的似乎是 std::piecewise_construct

.try_emplace()只是在内部使用 std::piecewise_construct

关于c++ - 无法使用 std::map::emplace 插入没有复制构造函数的类的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75637510/

相关文章:

c++ - 是否可以在 C++ 中推断类型转换为模板化类型?

c++ - 返回转发引用参数 - 最佳实践

c++ - std::mutex 如何在不同的线程中解锁?

c++ - 不能在复制构造函数中隐式调用的方法

c++ - Qt : setting text to a Qlabel with a pixmap and back

c++ - 字符指针未按预期初始化

c++ - 使用 integer_sequence 过滤元组

c++ - C++ 复制构造函数有什么大惊小怪的?

java - 我不了解复制构造函数的详细工作方式

c++ - 按类中的特定变量搜索