You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用std::map与unique_ptr时触发隐式删除拷贝构造函数的解决方法

解决包含std::unique_ptr的类存入std::map后的拷贝构造错误

问题根源

std::unique_ptr是独占所有权的智能指针,它的拷贝构造函数被显式删除。当你的Cb类包含std::unique_ptr成员时,编译器会自动删除Cb的拷贝构造函数和拷贝赋值运算符。因此任何需要拷贝Cb对象的操作(比如直接赋值、按值取出map元素)都会触发“调用隐式删除的拷贝构造函数”错误。

用std::move插入成功,是因为move操作转移了Cb对象的所有权(包括内部的unique_ptr),并没有触发拷贝。但取出时如果尝试按值获取对象,本质还是在做拷贝,所以错误重现。

解决方案

1. 使用引用/指针访问map中的对象(推荐,无所有权转移)

直接获取map元素的引用,避免拷贝对象,这样可以安全访问map中存储的Cb实例,且不会破坏map内的对象:

#include <iostream>
#include <map>
#include <memory>

class Cb {
public:
    std::unique_ptr<int> ptr;
    Cb(int val) : ptr(std::make_unique<int>(val)) {}
    // 若使用map的operator[],需确保Cb有默认构造函数
    Cb() = default;
};

int main() {
    std::map<int, Cb> cb_map;
    Cb cb(10);
    cb_map[1] = std::move(cb);

    // 方式1:通过operator[]获取引用(key不存在时会默认构造Cb)
    auto& cb_ref = cb_map[1];
    std::cout << *cb_ref.ptr << std::endl; // 正常输出10

    // 方式2:用find查找(更安全,避免不必要的默认构造)
    auto it = cb_map.find(1);
    if (it != cb_map.end()) {
        auto& cb_ref = it->second;
        std::cout << *cb_ref.ptr << std::endl;
    }

    return 0;
}

2. 用std::move转移map中对象的所有权

如果确实需要把Cb对象从map中取出并完全接管其所有权,可以用std::move转移,此时map中原位置的Cb对象会变为空(内部unique_ptr被置为nullptr):

auto cb_moved = std::move(cb_map[1]);
std::cout << *cb_moved.ptr << std::endl; // 正常输出10
// 此时cb_map[1].ptr已为空,直接访问会触发未定义行为

3. 改用std::shared_ptr共享所有权(适合多持有者场景)

如果业务需要多个地方同时持有Cb对象的所有权,可以把std::unique_ptr替换为std::shared_ptr。shared_ptr支持拷贝(通过引用计数共享所有权),此时Cb类的拷贝构造函数会被正常生成,插入和取出都可以直接使用拷贝操作:

class Cb {
public:
    std::shared_ptr<int> ptr;
    Cb(int val) : ptr(std::make_shared<int>(val)) {}
};

int main() {
    std::map<int, Cb> cb_map;
    Cb cb(10);
    cb_map[1] = cb; // 直接拷贝,无错误

    auto cb_copy = cb_map[1]; // 拷贝对象,shared_ptr引用计数增加
    std::cout << *cb_copy.ptr << std::endl; // 输出10
    std::cout << *cb_map[1].ptr << std::endl; // 同样输出10
    return 0;
}

方案选择建议

  • 仅需访问map中的对象:优先用引用/指针方案,无额外开销且安全。
  • 需要将对象从map中移除并接管所有权:用std::move方案。
  • 需要多组件共享对象所有权:改用std::shared_ptr方案。

内容的提问来源于stack exchange,提问作者Nick X Tsui

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 08:27:43