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

当存在(N)RVO时,移动构造函数何时会被实际调用?

关于(N)RVO阻止移动构造函数调用的实战解析

嘿,我来给你掰扯清楚这个C里的有意思的细节~从相关讨论里能看到,当函数按值返回对象时,**返回值优化(RVO)或者命名返回值优化(NRVO)**会直接“跳过”移动构造函数的调用,这可不是编译器瞎搞,是C标准允许的合法优化哦。

先看这个经典示例代码:

#include <iostream>
struct Foo {
    Foo() { std::cout << "Constructed\n"; }
    Foo(const Foo &) { std::cout << "Copy-constructed\n"; }
    Foo(Foo &&) { std::cout << "Move-constructed\n"; }
    ~Foo() { std::cout << "Destructed\n"; }
};
Foo makeFoo() { return Foo(); }
int main() { 
    Foo foo = makeFoo(); // 你可能以为这里会调用移动构造函数?
}

按照常规思路,makeFoo()里创建了一个临时的Foo对象,返回的时候应该会把这个临时对象通过移动构造传递给main里的foo。但实际运行起来,你会发现输出只有:

Constructed
Destructed

完全看不到“Move-constructed”的影子——这就是RVO在起作用!编译器直接在main函数中foo的内存位置上构造了那个原本要返回的临时对象,相当于把构造过程“合并”了,自然就不需要调用移动(或者拷贝)构造函数了。

如果你确实想看到移动构造的行为,可以通过编译选项禁用RVO(比如GCC/Clang用-fno-elide-constructors),这时候运行程序就能看到移动构造的输出啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:28:59