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

C++中复制消除(copy elision)与NRVO能否在递归函数中生效?

具名返回值优化(NRVO)在递归函数中是否生效?

在C++中,编译器允许执行复制消除(copy elision),其中的**具名返回值优化(NRVO)**可以让函数的局部变量无需通过move()转移到调用者栈帧,而是直接在调用者的栈帧中构造。那这种优化能不能在递归函数里生效?还是说应该让调用者手动传入存储空间?


假设NRVO生效的递归实现

vector<MyClass*> MyClass::GetHeirarchy() {
    vector<MyClass*> apclass;

    if (pclassParent)
        apclass = pclassParent->GetHeirarchy();

    apclass.push_back(this);
    return apclass;    
}

不依赖NRVO的实现

void MyClass::GetHeirarchy(vector<MyClass*>* papclass) {
    if (pclassParent)
        pclassParent->GetHeirarchy(papclass);

    papclass->push_back(this);
}

核心结论

  1. NRVO在这个递归场景里无法生效
    NRVO的生效条件是函数内的返回变量从构造到返回全程没有被赋值覆盖,但你写的递归代码里,每一层的apclass都会先接收上层递归返回的vector(要么移动赋值,要么拷贝赋值),再追加元素。这个赋值操作是无法消除的,编译器没法把所有递归层的apclass合并到最外层调用者的栈帧中,自然触发不了NRVO。

  2. 手动传入存储空间的实现更可靠高效
    第二种写法全程复用同一个vector,所有递归层直接往同一个容器里追加元素,没有任何额外的容器创建、移动或拷贝操作,性能稳定且不依赖编译器的优化行为——毕竟NRVO是编译器“可选”的优化,不同编译器或编译选项下可能失效,导致代码性能波动。

另外,第一种写法虽然符合“函数返回结果”的直觉,但实际运行时每一层递归都会生成临时vector,哪怕是移动赋值也存在指针拷贝的开销,相比之下第二种实现的效率更高。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 02:25:23