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

禁用RVO后返回局部对象为何调用move构造函数而非copy构造函数?

为什么返回局部左值时调用了移动构造而非拷贝构造?

问题描述

我定义了包含各类构造函数(默认、拷贝、移动)及赋值运算符的Snitch结构体,编写ReturnObj函数返回局部对象snit,在main函数中通过拷贝初始化接收返回值。使用g++ -fno-elide-constructors禁用RVO编译运行后,输出显示返回snit时调用了移动构造函数,但snit是局部左值,按预期应该调用拷贝构造函数初始化临时对象。我疑惑的是:这个局部对象在这里被当成xvalue了吗?

解答

这是C++标准规定的特殊规则:当return语句中的表达式是函数体内定义的非静态局部对象(且不是函数参数)时,即便它是左值,编译器也会自动将其视为亡值(xvalue),优先匹配移动构造函数。

本质上,这个规则是基于对象的生命周期——该局部对象在函数返回后马上就会被销毁,移动它不会产生任何安全问题,因此标准允许编译器优先选择更高效的移动构造。

你禁用RVO只是关闭了返回值优化,但这个“局部返回对象自动转为可移动”的规则依然生效,所以最终调用的是移动构造函数。

如果需要强制调用拷贝构造,可以通过std::as_const显式将其转为const左值:

return std::as_const(snit);

这样编译器就只能匹配拷贝构造函数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 02:09:54