结构化绑定中的const引用是否会延长分解对象的生命周期?

Rya*_*ing 27 c++ c++17 structured-bindings

书写是否const auto& [a, b] = f();延长从返回的对象的终身保障f(),或者至少对象ab必然?通过阅读提案,我没有看到任何明显的语言,以确保它确实存在,除非它只是被其他东西覆盖.但是,以下内容并未延长临时的生命周期,因此我不知道它将如何覆盖:

const auto& a = std::get<0>(f());
Run Code Online (Sandbox Code Playgroud)

在论文的顶部,似乎表明它已被覆盖

分解声明的cv-qualifiers和ref-qualifier应用于为初始化程序引入的引用,而不是单个成员别名

但是在实际标准的拟议措辞中,我看到的最接近的提法如下,但我不知道如何阅读它以获得我正在寻找的保证:

如果e是未分类的id-expression,命名从分解声明的identifier-list引入的左值或引用,则decltype(e)是分解声明规范中给出的引用类型

似乎gcc和clang都延长了返回对象的生命周期,直到基于wandbox实验的范围结束.一个实现我自己类型的所有铃声和口哨声的丑陋似乎延长了外部对象及其他数据成员的生命周期.

虽然几乎可以肯定作者的意图,但我想确切地知道这种语言可以保证这是安全的.

T.C*_*.C. 19

是.诀窍是要意识到,尽管外观,结构化绑定声明之前的部分[不适用于标识符列表中的名称.它们适用于声明隐式引入的变量.[dcl.struct.bind]/1:

首先,e引入具有唯一名称的变量.如果 分配表达初始化具有阵列型A和无REF-限定符存在,e具有类型cv A和每个元素是副本初始化或直接初始化来自的对应元素分配表达如通过的形式指定 初始化.否则,e定义为-if by

attribute-specifier-seq opt decl-specifier-seq ref-qualifier opt e initializer ;

声明永远不会被解释为函数声明,声明的声明部分以外的声明部分取自相应的结构化绑定声明.

名称被定义然后要么是用于元素别名e绑定到调用的结果,或者引用gete.

在你的例子中,它就像是(假设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);
Run Code Online (Sandbox Code Playgroud)

(除此之外,decltype(a)decltype(b)获得特殊处理以隐藏其参考性.)

很明显,第1行确实延长了f返回值的生命周期.