当存在(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
相关产品推荐
相关产品推荐

