c++11 - 为什么map emplace调用右值构造函数两次
问题描述
class twoMem {
int _a;
int _b;
public:
twoMem() {
std::cout << "default constructor" << std::endl;
}
twoMem(int a, int b) :_a(a), _b(b) {
std::cout << "constructor called" << std::endl;
}
twoMem(const twoMem& other) {
std::cout << "copy constructor called" << std::endl;
_a = other._a;
_b = other._b;
}
twoMem(const twoMem&& other) {
std::cout << "rvalue copy constructor called" << std::endl;
_a = other._a;
_b = other._b;
}
~twoMem() {
std::cout << "destructor called" << std::endl;
}
};
int main()
{
std::map<std::string, twoMem> myMap{};
myMap.emplace(std::make_pair("foo", twoMem{ 1, 2 }));
return 0;
}
输出:
constructor called
rvalue copy constructor called
rvalue copy constructor called
destructor called
destructor called
destructor called
解决方案
首先,make_pair
从twoMem
参数移动到pair<const char*, twoMem>
它返回。其次,emplace()
从那个移动到实际节点。
做了
myMap.emplace("foo", twoMem{ 1, 2 });
那么移动构造函数只被调用一次。这就是重点map::emplace
。
您可以通过这种方式实现零复制或移动构造函数:
myMap.emplace(std::piecewise_construct, std::make_tuple("foo"), std::make_tuple(1, 2));
虽然可以说这种治疗方法可能比疾病更糟,因为现在你正在构建和复制元组,这可能至少与复制一样昂贵twoMem
。
推荐阅读
- python - 我如何生成没有模型的 Django 站点地图
- flutter - 文本字段上的颤动滚动条
- google-cloud-platform - BigQuery 中的表视图是否受益于分区/集群优化?
- python - Python /由函数构建的字典中的错误顺序
- c++ - 命令提示符输入和输出
- php - Woocommerce 将订单备注添加到失败的订单管理员电子邮件
- python - Kaggle Titanic 项目输出问题(我提前为新手问题道歉)
- javascript - 如何删除数组中当前索引之前的项目?
- python - 使用按钮更改 UI 背景颜色
- windows-subsystem-for-linux - WSL 无法访问网络