当前位置: 首页 > 知识库问答 >
问题:

结构化绑定中的常量引用是否延长了分解对象的生存期?

凌成天
2023-03-14

写入常量是否自动

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

在这篇文章的顶部,它似乎表明它被覆盖了

分解声明的cv限定符和ref限定符应用于为初始值设定项引入的引用,而不是单个成员别名

但在实际标准的拟议措辞中,我看到的最贴切的提及如下,尽管我不确定如何阅读它以获得我想要的保证:

如果e是一个未被限定的id表达式,命名从分解声明的标识符列表中引入的左值或引用,则decltype(e)是分解声明规范中给出的引用类型

根据wandbox实验,gcc和clang似乎都会将返回对象的生存期延长到作用域结束。一个更丑陋的版本实现了我自己类型的所有功能,似乎延长了外部对象及其其他数据成员的生命周期。

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


共有1个答案

漆雕稳
2023-03-14

对诀窍是要意识到,尽管出现了这种情况,[前面的结构化绑定声明部分并不适用于标识符列表中的名称。它们适用于声明隐式引入的变量。[dcl.struct.bind]/1:

首先,引入一个具有唯一名称e的变量。如果初始值设定项中的赋值表达式具有数组类型A且不存在ref限定符,e具有类型cv A,并且每个元素都是从初始值设定项形式指定的赋值表达式的对应元素进行复制初始化或直接初始化的。否则,e被定义为

属性说明符seqoptdecl说明符seq ref限定符opte初始值设定项;

其中,声明从不被解释为函数声明,声明中除声明器id以外的部分取自相应的结构化绑定声明。

然后,这些名称被定义为e元素的别名或绑定到e上调用get结果的引用。

在您的示例中,它就像by(假设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返回值的生存期。

 类似资料: