结构化绑定中的const引用扩展了分解对象的寿命

Do const references in structured bindings extend the lifetime of the decomposed object?

本文关键字:对象 分解 引用 绑定 const 结构化 扩展      更新时间:2023-10-16

编写 const auto& [a, b] = f();是否保证延长从 f()返回的对象的寿命,或者至少对象 a and b绑定到?仔细阅读该提案,我看不到任何明显的语言,可以使我确定它确实可以,除非它只是被其他东西覆盖。但是,以下内容不会延长临时性的寿命,因此我看不到它将如何覆盖:

const auto& a = std::get<0>(f());

在纸的顶部,它似乎表明它已覆盖

分解声明的CV-定分机和参考定位符用于初始化器引入的参考,而不是单个成员别名

但是,在针对实际标准的拟议措辞中,我看到的最接近的是下面,尽管我不确定如何阅读它以获取我要寻找的保证:

如果e是无父母的ID表达,则命名lvalue或参考 从分解声明的标识符列表中引入, 声明类型(e)是指规范中给出的引用类型 分解声明

似乎GCC和Clang都会扩展对象的寿命,直到基于Wandbox实验的范围结束。为我自己类型实施所有钟声和哨声的一个丑陋的人似乎延长了外部对象及其其他数据成员的寿命。

尽管几乎可以肯定的是作者的意图,但我想确定该语言保证这是安全的。

是。诀窍是要意识到,尽管出现了,但在[之前,结构化绑定声明的一部分不适用于 dissineifier-list 中的名称。相反,它们适用于声明暗示引入的变量。[dcl.struct.bind]/1:

首先,引入了具有唯一名称e的变量。如果是 sigitment-expression initialerizer 中具有数组类型A,并且存在 ref-Qualifier e具有cv A类型,每个元素is copy-Initialized或从相应元素进行直接启动 分配表达的形式 initializer 。否则, e被定义为

属性 - 份seq 选择/sub> e initializer ;

,声明从未被解释为函数声明 以及声明的部分宣言宣言的部分是 取自相应的结构化结合声明。

然后将名称定义为e元素的别名,或者是在e上调用get的结果的引用。

在您的示例中,好像是通过(假设f返回两元素std::tuple):

const auto& e = f(); // 1
using E = remove_reference_t<decltype((e))>;
std::tuple_element<0, E>::type& a = get<0>(e);
std::tuple_element<1, E>::type& b = get<1>(e);

(除了decltype(a)decltype(b)以外,还获得了隐藏其参考性的特殊待遇。)

很明显,第1行确实延长了f的返回值的寿命。