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

如何将不可拷贝的LockWrap对象存入std::map?

解决无法将noncopyable派生类存入std::map的问题

你的问题核心在于:LockWrap继承自noncopyable(拷贝构造/赋值已被删除),且未定义移动构造/赋值函数,因此编译器不会生成默认的移动操作,导致std::map的常规插入/emplace操作(需要移动或拷贝元素)失败。以下是两种直接解决问题的方案:

方案一:原地构造元素(推荐,无需额外内存分配)

利用std::map::emplace结合std::piecewise_construct,直接在map的节点内存中构造LockWrap对象,完全避免移动或拷贝操作。修改main中的代码如下:

#include <tuple> // 需包含tuple头文件以使用piecewise_construct

int main() {
    std::mutex mut;
    typedef std::map<int, LockWrap> map_type;
    map_type locks_held;
    int id = 1;
    
    // 原地构造LockWrap对象到map中
    locks_held.emplace(
        std::piecewise_construct,
        std::forward_as_tuple(id), // 构造key的参数
        std::forward_as_tuple(std::ref(mut)) // 构造LockWrap的参数(传递mutex引用)
    );
}

原理

std::piecewise_construct允许我们分别传递构造pair的两个元素(key和value)的参数,std::forward_as_tuple将参数打包成tuple,最终map会直接在自身内存空间中构造LockWrap对象,全程不涉及LockWrap的移动或拷贝操作。

方案二:使用智能指针包装

如果原地构造的方式不符合需求,可以用std::unique_ptr包装LockWrap,智能指针支持移动操作,且存储指针不需要拷贝LockWrap本身:

#include <memory> // 包含unique_ptr头文件

int main() {
    std::mutex mut;
    typedef std::map<int, std::unique_ptr<LockWrap>> map_type;
    map_type locks_held;
    int id = 1;
    
    // 存入包装后的智能指针
    locks_held.emplace(id, std::make_unique<LockWrap>(mut));
}

原理

std::unique_ptr是可移动的,map中存储的是指针而非LockWrap对象本身,因此插入操作只需要移动智能指针,不会触发LockWrap的拷贝或移动逻辑。

内容的提问来源于stack exchange,提问作者calvin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 00:07:22