const 引用可以初始化爲不同類型的對象或者初始化爲右值(第 2.3.1 節),如字面值常量:
int i = 42;
// legal for const references only
const int &r = 42;
const int &r2 = r + i;
同樣的初始化對於非 const 引用卻是不合法的,而且會導致編譯時錯誤。其原因非常微妙,值得解釋一下。
觀察將引用綁定到不同的類型時所發生的事情,最容易理解上述行爲。假如我們編寫
double dval = 3.14;
const int &ri = dval;
編譯器會把這些代碼轉換成如以下形式的編碼:
int temp = dval; // create temporary int from the double
const int &ri = temp; // bind ri to that temporary
如果 ri 不是 const,那麼可以給 ri 賦一新值。這樣做不會修改 dval,而是修改了 temp。期望對 ri 的賦值會修改 dval 的程序員會發現 dval 並沒有被修改。僅允許 const 引用綁定到需要臨時使用的值完全避免了這個問題,因爲 const 引用是隻讀的。
非常贊同樓上的詳細解釋。我再帖一個小程序:
#include<stdio.h>
int global=3;
int other=4;
int& f(void){
return global;
}
int main(void){
int& g=f();
g=other;
printf("global=%d\n",global);
return 0;
}
> ./a.out
global=4
引用的處理實際是(gcc的實現)將對象地址放到eax,賦值就是給eax所指內存寫入操作。所以上面這個g可以被賦值兩次。
而立即數是沒有地址的,所以int&i=2不成立。const int &i=2相當於讓i指向一個隱含的地址(左值),該地址裏面放入2
記住,引用必須指向對象(左值)!