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

C++中向传值函数传递仅移动类型右值的底层机制解析

关于C++仅移动类型与值类别的问题解析

核心原因拆解

首先明确:std::thread是仅移动类型——它没有公开的拷贝构造函数/拷贝赋值运算符,只能通过移动操作转移资源。

1. Foo f(t); 编译失败的原因

这里t是左值(具名的对象),当调用Foo的构造函数时,形参std::thread t需要从实参初始化。因为实参是左值,编译器会尝试调用std::thread的拷贝构造函数来创建形参,但std::thread禁用了拷贝,所以直接编译报错。

2. Foo f{std::thread()}; 正常编译的底层过程

std::thread()是一个临时右值对象(没有名字,生命周期仅在当前表达式内),此时的初始化流程是:

  • 第一步:构造函数的形参std::thread t会通过std::thread的移动构造函数初始化——因为右值可以被绑定到std::thread&&类型的参数,移动构造函数会直接把临时对象的线程资源"转移"给形参t,而不是复制。
  • 第二步:构造函数内部的mT(std::move(t)),又通过一次移动构造,把形参t的资源转移给成员变量mT。
  • 整个过程没有任何拷贝操作,都是资源的移动转移,符合std::thread仅移动的特性,所以可以正常编译。

补充说明

C++中,当函数参数是值传递时:

  • 如果实参是左值,必须调用拷贝构造(或拷贝赋值)来初始化形参;
  • 如果实参是右值(临时对象、std::move转换后的对象),会优先调用移动构造(如果存在),避免不必要的拷贝,这也是C++11引入移动语义的核心目的之一。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 11:42:35