2016-07-28 46 views
1

給出下面的代碼示例;爲什麼一個const引用在分配一個l值和r值時行爲不同?

#include<iostream> 

using namespace std; 

int main(){ 
    int a = 4; 
    const int &b = a; 
    const int &c = a * 2; 
    a = 10; 
    cout << b << endl; 
    cout << c << endl; 
    return 0; 
} 

當我運行此,輸出是

10 
8 

分配L值和R值以常量引用時,爲什麼C++設計成不同的表現?

+2

對象c綁定到的對象與綁定的對象不同。 – GeorgeAl

+1

每次更改'a'時,你希望''''''可以從表達式'a * 2'自動地重新評估'c'?這是**太雄心勃勃**! – Nawaz

+0

是的,真正的問題是你認爲會發生什麼,以及爲什麼......當你考慮什麼是需要做出任何參考臨時涉及任何左值(S)總是反映任何變化左值(S ),事情很快變得荒謬無法管理,語法無望地模棱兩可,而且真的很可怕。從字面上看:RHS是一個臨時值,它是由'const'引用生命週期延長的。 _Effectively_,這就像聲明一個名爲'c'的const'lvalue,而不是引用,雖然機制當然是後者。 –

回答

5

表達:

const int &c = a * 2; 

所得參考c不結合a。相反,它將它綁定到表達式a * 2的結果rvalue,該值是與a不再有任何關係的臨時對象 - 因此更改a不會影響它。

這與b相反,它是對象a的參考。

4
const int &b = a; 
const int &c = a * 2; 

b的這裏爲a的引用(別名);由於a更改值,b將反映這一點。

c綁定到作爲由表達式a * 2計算出的臨時對象,如a計算之後改變值時,計算不重新計算,的c值保持因爲它最初計算。

0

其他答案已經解釋了爲什麼你得到你得到的輸出。然而,讓我們假設你想要

const int &c = a * 2; 
a = 10; 
cout << c << endl; 

打印20。這是可能的,但不能直接使用const ref,例如像這樣:

struct myref { 
    const int& x; 
    myref(int& x) : x(x) {} 
    operator int() { return x*2;} 
}; 

int main() { 
    int a = 0; 
    myref c(a); 
    a = 10; 
    std::cout << c << std::endl; 
} 

不過,我強烈建議你不要使用這個代碼,我只是想證明它是可能的(我把「這是過於雄心勃勃」作爲一個挑戰評論)。

我想用lambda表達式可以以更加優雅的方式完成,不幸的是我對他們不那麼熟悉。

+0

很簡單 - 'auto myNonRef = [&x] {return x * 2; };/* ... */std :: cout << myNonRef()<< std :: endl;' - 儘管顯然你被侷限於函數調用語法,因爲lambda不能像你的自定義類那樣有轉換運算符。 –

+0

@underscore_d但是我們可以編寫一個類似我的結構,它將lambda作爲參數,至少我的方法是靈活的。但是,我強烈懷疑是否使用'operator int'是一個好主意 – user463035818

+0

True,模板結構接收和存儲lambda。但是,我不確定這有多少實際用處,至少不是在一般情況下。這與參考概念完全正交。 –

相關問題