Skip to content

败犬日报 2025-08-04

1. 结构化绑定的变量不触发 NRVO

cpp
#include <iostream>
#include <tuple>
#include <utility>

struct T {
    T() = default;
    T(const T&) { std::cout << "Copy constructor called\n"; }
    T(T&&) noexcept { std::cout << "Move constructor called\n"; }
};

std::pair<int, T> foo() {
    return {std::piecewise_construct, std::forward_as_tuple(42),
            std::forward_as_tuple()};
}

T func() {
    auto [x, y] = foo();
    // copy!!!
    return y;
}

int main() {
    T t = func();
    return 0;
}

输出 "Copy constructor called"。

结构化绑定实际上仍然是单个变量,然后给每个字段一个别名,而非直接构建出多个变量。

nrvo 是直接在返回值那个地址对象上构造局部变量。对于子对象,你没法把这个子对象换成函数返回值,其它子对象用原本局部变量的。所以一定没法 rvo/nrvo。

所以要写成 return std::move(y);