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

为何NRVO在结构化绑定场景下无法生效?

核心问题部分

请参考以下示例代码:

#include <iostream>

struct movable
{
    movable() {
        std::cout << "movable()\n";
    }

    movable(movable&&) noexcept {
        std::cout << "movable(&&)\n";
    }

    movable(const movable&) noexcept {
        std::cout << "movable(const &)\n";
    }

    ~movable() {
        std::cout << "~movable()\n";
    }
};

movable rvo()
{
    return {};
}

movable nrvo()
{
    movable m;
    return m;
}

movable cnrvo()
{
    const movable m;
    return m;
}

movable binding_nrvo()
{
    struct binding { movable m; };
    auto [m] = binding{};
    // explicit move is required
    // return std::move(m);

    // otherwise a copy would be made
    return m;
}

int main()
{
    {
        std::cout << "rvo:\n";
        movable m = rvo();
    }

    {
        std::cout << "\nnrvo:\n";
        movable m = nrvo();
    }

    {
        std::cout << "\ncnrvo:\n";
        movable m = cnrvo();
    }

    {
        std::cout << "\nbinding_nrvo:\n";
        movable m = binding_nrvo();
    }

    return 0;
}

使用-std=c++17 -O3编译后的输出如下:

rvo:
movable()
~movable()

nrvo:
movable()
~movable()

cnrvo:
movable()
~movable()

binding_nrvo:
movable()
movable(const &)
~movable()
~movable()

我了解NRVO对“包装”值无效,例如必须显式使用std::move(如return std::move(std::get<0>(tuple));)来避免拷贝。

但此处是按值绑定:auto [m] = binding{};,我认为m是独立对象,为何NRVO仍不生效?

背景说明部分

本问题并非聚焦此部分,仅作背景补充:
我尝试用结构化绑定实现类似Go语言的错误处理控制流,理想写法如下:

const auto [value, err] = getSome();
if (err)
  return err;

在没有expected类返回类型的情况下,这对我而言是无需异常的最简洁控制流。我原本期望const修饰的err能像cnrvo()示例那样触发NRVO,但实际并未生效。
而且由于必须使用std::move,value也无法设为const。最终写法变成了:

auto [value, errGetSome] = getSome(); // can't have several `err` in the scope
if (!errGetSome)
  return std::move(errGetSome);

// just promise not to modify `value`
const auto& actualValue = value;

……这完全违背了初衷。
无论如何,我希望得到核心问题的解答。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 09:44:52