2016-12-16 38 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的返回值的生命週期。

相關問題