2016-12-16 37 views
27

写作const auto& [a, b] = f();保证延长从f()返回的对象的寿命,还是至少要将对象ab绑定到?通过the proposal阅读我没有在语言中看到任何明显的东西,以确保它不会被其他东西所覆盖。但是,下列情况不延长临时的寿命,所以我看不出它如何被覆盖:在结构化绑定中执行const引用是否延长分解对象的生命周期?

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

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

的cv修饰符和分解声明的REF-限定符被施加到引入用于初始化的基准,而不是为单独的构件别名

但在拟议措辞的实际标准,最接近提我看到的是贝洛W,虽然我不知道该如何解读它让我在寻找担保:

如果e是一个加括号的ID表达从命名的标识符列表介绍了一个左或引用 分解声明, decltype(e)是如在 说明书中给出的分解声明

似乎gcc和铛既延长对象的生命周期返回直到范围的端部基于所述引用的类型一个wandbox experiment。为我自己的类型实现所有的花里胡哨的uglier one似乎延长了外部对象及其他数据成员的生命周期。

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

回答

17

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

首先,引入具有唯一名称e的变量。从的相应元素 如果初始化赋值表达式具有阵列型A和无REF-限定符存在,e具有类型cv A和每个元素是副本初始化或直接初始化赋值表达式,如 初始化程序的形式所指定的。否则,e被定义为 - 如果由

属性说明符-SEQ选择DECL说明符-SEQREF-限定符选择e初始化;

其中声明从未解释为函数声明 和声明的比说明符-ID从相应结构绑定声明采取 以外的部分。

的名称被定义然后要么是绑定到调用eget的结果的e元件或引用别名。

在您的例子,就好像通过(假设f返回两个元素std::tuple):(除decltype(a)decltype(b)得到特殊待遇,以隐藏自己的referenceness)

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); 

第1行确实延长了f的返回值的生命周期。

相关问题