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

关于《C++ Concurrency in Action》中joining_thread传值构造的疑问

关于《C++ Concurrency in Action》中joining_thread构造函数传值的疑问解答

首先明确核心前提:std::thread是不可拷贝的,它的拷贝构造函数被显式删除了,所以你提到的joining_thread jt(t);(t是左值std::thread对象)根本无法通过编译——这不是joining_thread的设计问题,是std::thread本身的特性决定的。

那为什么joining_thread的第二个构造函数要按值传递std::thread?主要有两个原因:

  • 简化代码逻辑,兼容多场景:按值传递可以同时处理两种情况:
    1. 传入临时右值(比如joining_thread jt{std::thread(fct)};),此时参数会直接通过移动构造创建,不需要额外重载;
    2. 传入显式std::move后的左值线程(比如std::thread t(fct); joining_thread jt(std::move(t));),此时参数也是通过移动构造生成,再转移到类内部的thread成员中。
      全程没有任何拷贝操作,因为std::thread不支持拷贝,所谓的“传值”本质是移动语义的复用。
  • 明确所有权转移语义:joining_thread的设计目标是接管线程的所有权,并在自身析构时负责join该线程。按值传递强制调用者明确表达所有权转移的意图——要么传临时对象(天然完成转移),要么显式用std::move交出左值线程的所有权,避免出现“线程被多个对象同时持有”的模糊情况。

而你提到的thread_guard设计不同,是因为它的定位是临时保护已有线程,不接管所有权,只是确保在自身析构时join传入的线程,所以它需要接受左值引用,保持对原线程对象的关联,而不是转移所有权。

你之前的误解在于误以为“按值传递会复制线程”,但实际上std::thread不允许拷贝,这里的传值只是利用了移动语义,最终实现的是线程所有权的安全转移,而非创建副本。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 21:02:10