我正在尝试编译以下代码:
#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
的复制构造函数。
所以我的问题是双重的:
- 为什么需要复制构造函数?
- 如何重写代码以便不需要复制构造函数(由于类的复杂性,编写起来有点棘手,为简洁起见,此处省略)?
最佳答案
在 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/