2013-02-06 44 views
18

我被以下示例在聊天:哪種標準措辭告訴我們,只有「ref-to-const」臨時生命週期延長「有效」?

#include <iostream> 
struct foo { ~foo() { std::cout << "destroying!\n"; } }; 
const foo& func(const foo& a, const foo&) { return a; } 

int main() 
{ 
    foo x; 
    const foo& y = func(foo(), x); 
    std::cout << "main\n"; 
} 

Output

destroying! 
main 
destroying! 

這似乎表明,foo臨時的壽命沒有延伸到的main整體,即使它得到綁定到該範圍內的ref-const

那麼可以推測,延長壽命只是「一次工作」;即在func的參數初始化時應用,但不通過連續綁定傳遞。

我的解釋是否正確?如果是這樣(以及是否有任何單獨的段落可直接適用),定義此行爲的標準措辭是什麼?

+0

「func」的第二個參數是什麼?如果將它(和'x')關閉,會發生什麼? –

+0

@KonradRudolph:我猜,它是爲了演示相對於文本'「main」輸出的破壞順序。 –

回答

7

這是兩個問題報告的主題,http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1299http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1568

前者問題的報告,其中我是記者,是爲了覆蓋所有這些情況下,一個引用綁定到一個臨時對象,但並非是延長壽命,。該問題正文中的描述僅提到了與臨時表達式混淆的價值(實際上決定了他們評估的生命週期是否延長或不延長)。但是左值和x值同樣在標準中與這些混淆。在static_cast的情況下發生的一個例子是問題編號#1568(其中使用「臨時變量」進一步混淆了此事)。

實際上,這樣的:

臨時結合到在一個函數調用(5.2參考參數。2)一直持續到包含該調用的完整表達式的完成。

與本段落中的其他規則相矛盾。因爲臨時數據綁定到都是函數調用中的引用參數和本地自動引用變量。

+0

是的,你和詹姆斯已經說服了我,「除了」這個詞不會消除這個段落的規則,因爲「except」一次只能應用於一個場景,因此不能消除兩個或兩個更矛盾的情況。 –

8

你幾乎是正確的。這種行爲實際上來自於函數調用,並不是因爲任何一種「只能工作一次」的規則。

這裏的整個壽命延長「功能」的措辭,與相關的規則以粗體強調:

[C++11: 12.2/5]:[..]到的引用綁定暫時或臨時性的即是到該參考被結合的子對象的完整的對象持續基準的壽命除了

  • [..]
  • 臨時綁定到函數調用(5.2.2)中的引用參數,直到完成包含調用的完整表達式。
  • [..]
+0

但在這種情況下,臨時也被綁定到const引用'y'。那麼哪個參考控制其使用期限? –

+1

@JamesKanze:我看到「除了」列表優先。 –

+0

我有點不明白你的意思,但我仍然認爲它是模棱兩可的,如果這是意圖,有點指定它的折磨方式。首先,你保證延長生命週期的唯一基礎是否引用是否被綁定到一個臨時的,然後你消除所有可能導致間接性的情況,希望你已經得到了他們所有的(他們可能沒有的) 。 –

3

這適用於這裏是常識的規則。標準是 措辭不佳,事實上確保這一點。但是沒有實用的實用方法。

+0

你是什麼意思?沒有切實可行的方法來實施限制,或實施目前尚未發生的壽命延長? –

+0

@LightnessRacesinOrbit沒有實際的方法強迫臨時的生命週期擴展到它所綁定的最後一個引用。 –

+0

我認爲@詹姆斯正在談論我在我的回答中總結的內容。 –

1

也許我有點慢,但對我來說,它不清楚這個問題的解決方案是從閱讀其他答案。因此,我修改了顯示的代碼並希望爲其他人進行總結:答案是,您獲得未定義的行爲如果您訪問y

運行這段代碼:

struct foo { 
    int id; 
    foo(int id) : id(id) { std::cout << "ctor " << id << std::endl; }; 
    ~foo() { std::cout << "dtor " << id << std::endl; } 
}; 
const foo& func(const foo& a, const foo&) { return a; } 

int main(int argc, char** argv) { 
    foo x(1); 
    const foo& y = func(foo(2), x); 
    std::cout << "main " << y.id << std::endl; 
    return 0; 
} 

輸出對我來說是:

ctor 1 
ctor 2 
dtor 2 
main 2 
dtor 1 

但線路main 2不確定的行爲

相關問題