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

使用insert函数向std::map添加元素失败的排查与解决

修复std::map插入包含std::condition_variable的对象失败问题

问题原因

你的khaos_event类包含std::condition_variable成员,而std::condition_variable是不可拷贝的类型(它的拷贝构造函数被显式删除)。这导致khaos_event类的默认拷贝构造函数和拷贝赋值运算符被编译器自动禁用。

当你调用std::make_pair(1, khaos_event())时,需要创建std::pair<uint32_t, khaos_event>对象,这个过程会尝试拷贝临时的khaos_event实例,但因为拷贝构造函数不存在,最终触发编译错误。

修复方案

以下是几种可行的解决方式:

1. 使用std::map::emplace直接在容器内构造对象

emplace可以直接在map的内存空间中构造khaos_event对象,完全避免拷贝或移动操作:

int main()
{
  std::map<uint32_t, khaos_event> events;
  events.emplace(1, khaos_event()); 
  // 更简洁的写法:events.emplace(1, {});
  ...
}

2. 利用移动语义转移临时对象

std::condition_variable支持移动操作,编译器会为khaos_event自动生成默认的移动构造函数。可以用std::move将临时对象转移到pair中,避免拷贝:

int main()
{
  std::map<uint32_t, khaos_event> events;
  events.insert(std::make_pair(1, std::move(khaos_event())));
  // 也可以直接构造带移动语义的pair:
  // events.insert(std::pair<uint32_t, khaos_event>(1, std::move(khaos_event())));
  ...
}

3. 显式声明移动构造函数(可选)

如果后续给khaos_event添加了自定义的拷贝构造/赋值函数,编译器会停止自动生成移动构造,此时可以显式声明:

class khaos_event
{
public:
  khaos_event() = default;
  ~khaos_event() = default;
  // 显式声明默认移动构造和赋值
  khaos_event(khaos_event&&) = default;
  khaos_event& operator=(khaos_event&&) = default;
  
  bool wait(uint32_t timeout){
    std::chrono::milliseconds millis{timeout};
    std::unique_lock<std::mutex> lock(m_mtx);
    return m_cv.wait_for(lock, millis) == std::cv_status::no_timeout;
  };
  void notify(void){
    std::unique_lock<std::mutex>lock(m_mtx);
    m_cv.notify_one();
  };
private:
  std::condition_variable m_cv;
  std::mutex m_mtx;
};

关键理解点

  • 当类包含不可拷贝的成员时,类的拷贝操作会被编译器自动禁用,必须通过移动语义或直接在容器内构造的方式添加对象。
  • std::map::insert如果接收需要拷贝的对象,而对象不可拷贝时就会报错,改用emplace或移动操作可以绕过拷贝需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 06:10:00