删除拷贝和移动构造、赋值运算符的struct如何存入C++容器
错误原因
Data同时继承NonCopyable和NonMovable后,拷贝构造、移动构造函数都被隐式删除,属于既不可拷贝也不可移动的类型。你原有代码中调用emplace时传入了临时构造的Data对象,需要调用拷贝/移动构造才能完成容器内std::pair<const std::string, Data>的初始化,没有匹配的构造函数因此编译报错。
解决方案
方案1:分段原位构造(无额外开销)
利用std::piecewise_construct直接在容器分配的内存上分段构造键和值,全程不需要生成Data临时对象,也不需要调用拷贝/移动构造,性能最优。
修改插入代码为:
table.emplace( std::piecewise_construct, std::forward_as_tuple("test"), std::forward_as_tuple("data", 10) );
完整可运行main函数示例:
int main(int argc, char** argv) { std::unordered_map<std::string, Data> table; table.emplace( std::piecewise_construct, std::forward_as_tuple("test"), std::forward_as_tuple("data", 10) ); return 0; }
方案2:容器存储智能指针(写法更简单)
如果不想记忆分段构造的语法,可以把容器的值类型改为智能指针,仅需要移动智能指针即可完成插入,不需要修改原有类定义。
修改后的代码:
int main(int argc, char** argv) { std::unordered_map<std::string, std::unique_ptr<Data>> table; table["test"] = std::make_unique<Data>("data", 10); return 0; }
该方案有一次堆内存分配的开销,优点是写法直观易维护。
内容的提问来源于stack exchange,提问作者QuickDzen
相关产品推荐
相关产品推荐

