提问人:Silverspur 提问时间:3/5/2023 最后编辑:HolyBlackCatSilverspur 更新时间:3/5/2023 访问量:183
不能使用 std::map::emplace 插入没有复制构造函数的类的对象
Cannot use std::map::emplace to insert an object of a class with no copy constructor
问:
我正在尝试编译以下代码:
#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
所以我的问题有两个方面:
- 为什么需要复制构造函数?
- 我怎样才能重写我的代码以不需要复制构造函数(由于类的复杂性,编写起来有点棘手,为了简洁起见,这里省略了)?
答:
5赞
HolyBlackCat
3/5/2023
#1
在 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 &
的参数直接指向 std::p air
的构造函数。如果您检查构造函数,则唯一可以默认构造第二个元素(不包括该对自己的默认构造函数)的构造函数似乎就是那个。.emplace()
std::piecewise_construct
而 .try_emplace()
只是在内部使用。std::piecewise_construct
评论