C++中“非常量引用的初始值必須是左值”的處理方法
1 左值和右值
在C++中,左值可以出現在賦值語句的左邊和右邊;右值只能出現在賦值語句的右邊,不能出現在賦值語句的左邊。變數是左值,常量是右值。
2 引用
引用(reference)為物件起了另外一個名字,引用型別引用(refers to)另外一種型別。通過在變數名前新增“&”符號來定義。引用具體的使用方法請參考《C++的引用與過載函式》。
3 非常量引用的初始值必須是左值
3.1 產生原因
自定義函式increment()的程式碼為
void increment(double& x)
{
x += 1.0;
}
在呼叫該函式時,有如下程式碼
increment(5);
因為increment()函式的形參是double&,而呼叫時的實參是整形常量。因此,在呼叫increment()函式時實際上存在一個隱式的型別轉換
double& temp = (double)5;
x = temp;
假設此後在increment()中對形參x進行修改,實際上就是對常量進行了修改,這顯然是不能允許的。所以,在對非常量進行初始化時,該初始值必須是左值,而不能是右值。因此,會顯示“非常量引用的初始值必須是左值”的錯誤資訊。
3.2 解決方法
有兩種方法可以解決以上問題,一是避免隱式轉換;二是避免修改形參。
3.2.1 避免隱式轉換
可以使用如下方法避免隱式轉換
double i = 5.0l;
increment(i);
避免了隱式轉換,也就是避免了對非常量引用的初始化。
3.2.2 避免修改形參
將increment()函式的形參型別修改為const double&,則在進行隱式轉換時就可以用常量(右值)對其進行初始化了。
void increment(const double& x)
{
}
需要注意的時,因為此時形參x的值是常量,所以在increment()函式內部中不能對其進行修改。
4 實戰
在CSDN論壇中有朋友提到如下問題
定義了一個Time類,過載cout輸出time類時報錯,其報錯的資訊即為“非常量引用的初始值必須是左值”。
ostream & operator <<(ostream& os,Time& _t)
{
os<<_t.hour<<':'<<_t.minute<<':'<<_t.second<<endl;
return& os;
}
在《C++函式的返回值(上)》“當函式的返回值是非引用變數時,會用一個臨時變數來儲存該返回值;當函式的返回值是引用變數時,不使用臨時變數,直接返回該引用”。
因為其過載的<<操作符的返回值是一個引用變數,因此不存在“3 非常量引用的初始值必須是左值”中提到的臨時變數隱式轉換的問題。該操作符return的是&os,其含義是os的地址,該地址是一個常量,即右值;而操作符返回值是一個非常量的引用,因此會產生“非常量引用的初始值必須是左值”的報錯資訊。
修改的方法為將過載的<<操作符的return改為
return os;
即可。
相關文章
- C++左值引用與右值引用C++
- c++ 左值引用與右值引用C++
- C++ 右值引用和左值引用C++
- c++中的左值與右值C++
- 左值、右值、左值引用,右值引用,std::move函式函式
- 9個必須掌握的Javascript處理陣列的方法JavaScript陣列
- C++ 11 中的右值引用C++
- 【C++】類初探常量成員函式與建構函式初始值列表C++函式
- 基本資料型別和引用型別的初始值資料型別
- OracleParameter.UdtTypeName的值必須是全大寫!Oracle
- 思考是必須的
- C++ 左值和右值C++
- 聲音很差,必須要處理下了
- Java中處理異常的9個最佳實踐,你必須要知道!Java
- C++11 左值引用和右值引用與引用摺疊和完美轉發C++
- 做大資料必須瞭解的多種處理框架大資料框架
- 引數傳遞方式必須是const引用傳遞
- C++右值引用C++
- sql語句中常量的處理SQL
- C++ 引用 (交換兩個數的值)C++
- 非平衡資料集的機器學習常用處理方法機器學習
- C++霧中風景10:聊聊左值,純右值與將亡值C++
- C++中的字串編碼處理C++字串編碼
- C++中的預處理(上) (轉)C++
- C++中的預處理(下) (轉)C++
- 影像處理或其他多媒體處理中的值溢位處理
- 如何處理JavaScript 中的貨幣值?JavaScript
- Git中~你必須掌握的!Git
- C++筆記 11:在operator中處理“自我賦值“C++筆記賦值
- Smartform中的長文處理方法ORM
- Oracle 排序中常用的NULL值處理方法Oracle排序Null
- 【C#】-對於Null值的處理方法C#Null
- C中int main()必須reture一個值嗎AI
- 常量引用或指向常量的指標,其所指物件可以是非const物件(C++)指標物件C++
- 為什麼Java的main方法必須是public static void?JavaAI
- 物件資料成員的初始值物件
- Java 中的方法引用Java
- 這裡是值引用還是指標引用?指標