2016-09-27 50 views
13

爲什麼C++委員會決定const引用應該延長臨時對象的生存期?爲什麼const引用延長rvalues的生命週期?

這個事實已經在網上進行了廣泛的討論,包括這裏在stackoverflow。該權威資源解釋說,這種情況大概是這樣的GoTW:

GotW #88: A Candidate For the 「Most Important const」

什麼是這個語言功能的原理是什麼?它是否已知?

(另一種選擇將是臨時工的壽命沒有任何出處和延伸。)


我自己的寵物理論的基本原理是,這種行爲可以讓物體隱藏實現細節。通過這條規則,成員函數可以在不改變客戶端代碼的情況下,將值或常量引用返回到已經存在的值。例如,矩陣類可能能夠返回行向量和列向量。爲了最小化副本,根據實現情況(行主專欄和專欄專欄),可以將其中一個或另一個作爲參考返回。無論哪個不能被引用返回,都必須通過複製並返回該值來返回(如果返回的矢量是連續的)。庫編寫者可能希望在未來改變實現方式(行主要vs列專業),並防止客戶編寫強烈依賴於實現是主要行還是列主要的代碼。通過讓客戶接受返回值爲const ref,矩陣類可以返回const refs或值而不會對客戶端代碼做任何改變。無論如何,如果原來的基本原理是已知的,我想知道它。

+0

使用代理對象可以更優雅地解決矩陣示例。 – 5gon12eder

+2

你必須檢查「設計與演化的C++」的權威答案。但我強烈懷疑這個問題有一個客觀的答案 - 個人寵物理論並不重要。 – MSalters

+0

@ 5gon12eder我認爲你所建議的是我試圖通過規定返回的矢量必須是連續的(無論出於何種原因...)的先決條件。 – Praxeolitic

回答

14

它是在1993年提出的,其目的是消除綁定到引用時臨時對象的不一致處理。

那時候,沒有RVO這樣的東西,所以簡單地禁止一個臨時引用和一個引用的綁定就是性能問題。

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1993/N0345.pdf

+1

哇,那時我已經10歲了。有趣的是確實知道原因。 +1鏈接到論文。 – skypjack

+2

@skypjack 1993年是我第一次放棄編程的一年,因爲我想要一些冒險...... –

+0

你的第二段對我來說並不清楚。你能否描述一種情況:複製一個臨時的(RVO可能可以避免的,但據說沒有完成的)的性能損失可以通過綁定一個臨時參考文件來規避?當然沒有創建一個懸而未決的參考。 –

2

你不會質疑爲什麼const引用被允許綁定到臨時對象,而只是爲什麼它們延長這些臨時對象的生存期。

考慮以下代碼:

struct A 
{ 
    void foo() const; 
}; 

A bar(); 

const A& a = bar(); 

a.foo();    // (1) 

未定義的行爲如果臨時通過bar()返回的壽命不延長,那麼a任何使用(由線例示(1))將導致。這會使綁定到臨時對象的非參數const引用完全無用。


EDIT(尋址OP's comment):

因此,真正的問題應是爲什麼const引用變量(即不是函數參數)被允許結合到臨時。我不知道它的原始理由(Richard Hodges' answer可能是唯一的理由),但它爲我們提供了一個有用的功能。考慮下面的例子:

struct B 
{ 
    virtual void foo() const; 
}; 

B bar(); 

const B& b = bar(); 

b.foo();    // (1) 

這個例子與前一個唯一的區別是,B::foo()是虛擬的。現在,如果我們決定引入一個新類D作爲B的子類,並將bar()的返回類型從B更改爲D,該怎麼辦?

struct B 
{ 
    virtual void foo() const; 
}; 

struct D : B 
{ 
    virtual void foo() const; 
}; 

//B bar(); 
D bar(); 

const B& b = bar(); 

b.foo(); // This will call D::foo() 

// In the end the temporary bound by b will be correctly destroyed 
// using the destructor of D. 

因此,綁定到臨時對象的const引用簡化了利用動態多態對於由值返回的對象的優勢。

+0

正確的答案,你可以添加一些關於參考表達式的右值和左值類型嗎? – Trevir

+0

@特雷維爾對不起,但我不明白如何可以改善答案(關於OP的問題)。 – Leon

+1

除非我感到困惑,否則這個答案看起來有點過於誇張。我不知道這個問題的措辭是否具有誤導性,但我並不是故意暗示它對於const引用來綁定臨時對象而言有意義,但不能延長它們的生命週期。這個問題的目的是爲了說明爲什麼const引用可以綁定臨時對象*並延長它們的生命週期。 – Praxeolitic

相關問題