2011-04-28 79 views
4

我的代碼不能編譯。什麼是const關鍵字必需

int foobar() 
{ 
    // code 
    return 5; 
} 

int main() 
{ 
    int &p = foobar(); // error 
    // code 

    const int& x = foobar(); //compiles 
} 

爲什麼添加關鍵字常量使代碼編譯?

+0

如果刪除'&'即使它成爲一個值而不是引用,它也可以工作。 – 2011-04-28 18:09:16

回答

9

在C++臨時表不能綁定到非常量引用。

int &p = foobar(); 

的右值表達foobar()生成臨時不能被綁定到p因爲它是一種非const引用。

const int &x = foobar(); 

附加臨時到x這是常量的參考延長其壽命。這是完全合法的。

+0

我不太關注。這是否隱含導致臨時存儲在堆棧上更長的時間(無論「更長」是什麼)?或者是'x'被綁定到文字5而不是'foobar'返回時創建的5的臨時副本? – Cheezmeister 2011-06-23 20:16:45

4

因爲foobar()正在返回的值;這個結果是暫時的。你不能有一個非常量的臨時引用。

如果這不是真的,這段代碼會做什麼?

int &x = foobar(); 

x = 1; // Where are we writing to? 
+2

當我們做const const&x = foobar(); std :: cout <<&x;'。他們的生活臨時擴展是適當的對象,他們可以有'可變'數據成員,沒有根本原因他們不能被非const引用引用,它是不允許的。 – 2011-04-28 17:25:01

2

正如其他人所說,你可以採取一個const,但不是非const引用臨時。

在實踐中會有危險,在允許非const引用臨時對象:現在

#include <iostream> 
void foo(int &i) { 
    i = 5; 
} 

int main() { 
    long l = 4; 
    foo(l); 
    std::cout << l << "\n"; 
} 

l可以隱式轉換爲int,所以如果臨時非const引用在這裏允許的話大概foo將傳遞一個對該轉換結果的引用,與foo需要const int &時實際上相同。這項任務將臨時完成,然後在臨時銷燬時丟棄。這很可能是一個令人困惑的錯誤,而不是預期的結果。

我不知道是否有一個整潔的一套規則,允許在某些情況下,但不是在危險/討厭的人來臨時對象非const引用,但即便如此,C++標準並沒有包括它們。請注意,C++ 0x具有右值引用,它允許您使用C++ 03無法完成的臨時對象做一些額外的事情。