2010-02-23 85 views
9

有人可以向我解釋爲什麼這兩個語句有區別嗎?在C++中引用初始化

class A{}; 

const A& a = A();   // correct 

A& b = A();    // wrong 

它說,從臨時型A

A&類型的非const引用 無效初始化爲什麼const事嗎?

回答

14

非const引用必須用l值初始化。如果你可以用臨時文件初始化它們,那麼下面會做什麼?

int& foo = 5; 
foo = 6; // ?! 

const引用有他們延長了裁判的生命的特殊屬性,因爲它們是const,有沒有可能,你會嘗試修改一些不內存坐。例如:

const int& foo = 5; 
foo = 6; // not allowed, because foo is const. 

請記住,引用實際上必須引用某些內容,而不僅僅是臨時變量。例如,以下內容有效:

int foo = 5; 
int& bar = foo; 
bar = 6; 
assert(foo == 6); 
+1

等等,這是否意味着我可以使用'const classA&ref = ReturnsClassAByValue();'?我想臨時會死在下一行。 – Lucas 2010-02-23 02:10:18

+2

是的,你可以使用它。臨時將持續只要參考變量:http://herbsutter.spaces.live.com/blog/cns!2D4327CC297151BB!378.entry – 2010-02-23 02:30:56

+1

真棒,謝謝。就這樣,你每天都會學到新的東西...... – Lucas 2010-02-23 02:37:08

1

對於臨時/右值,您只能有一個const引用。

您可以對非臨時/左值具有非常量引用。

A a; 
A& b = a; 

我相信原因是增強的事實,右值是暫時的,因爲在能夠修改是要暫時消失的東西價值不大。

+1

授予;我認爲OP正在尋找原因。 – fbrereto 2010-02-23 00:45:15

1

在C++語言中,將非常量引用附加到右值是非法的,儘管將常量引用附加到右值是完全可以的。例如,這是法律

const int& r = 5; 

雖然這不是

int &r = 5; // ERROR 

由表達式A()返回A類型的臨時對象是一個rvalue,因此上述規則中的情況下也適用。

+0

右值是一個未命名的臨時值,如函數的返回值。 – thebretness 2010-02-23 00:47:30

+0

@thebretness:不一定。例如,枚舉常量是一個右值,但它是*名稱*。 – AnT 2010-02-23 00:51:54

3

關於此的術語有點混淆;你可能想進一步研究它們。下面是簡單的答案,但:

您分配一個臨時對象給一個變量(調用類的構造函數的結果)。臨時對象是一個R值。您不能將R值分配給非常量參考。

您可以爲常量引用指定一個R值,雖然允許它的理由很模糊。

0

因爲標準是這樣說的:

§8.5.3.5......否則,參考應是一個左值參考非易失const型...

但是,如果你想讓它非常多,你可以得到它:

#include <iostream> 
int main() 
{ 
    const int & cr=5; 
    int & r=const_cast<int &>(cr); 
    r=6; 
    std::cout<<r; 
} 
// outputs 6 with c++/clang++, Debian 8, amd64 

但要知道,應該不斷CR爲const的更多,也和你承擔不確定的行爲。 (§1.9(4))

正如上述代碼所示,沒有任何技術上的差異。相反,設計師們對用戶使用非const引用臨時對象的做法做了惡夢。