败犬日报 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);
。