今天遇到一個關於C++引用的錯誤,說實話以前確實一直沒注意到過引用還有這個規則
1>------ 已啟動生成: 項目: OpenGL, 配置: Debug Win32 ------ 1>Game.cpp 1>d:\18482\visual studio\source\repos\opengl\opengl\game.cpp(55): error C2664: “void SpriteRenderer::DrawSprite(Texture2D &,glm::vec2,glm::vec2,GLfloat,glm::vec3)”: 無法將參數 1 從“Texture2D”轉換為“Texture2D &” 1>d:\18482\visual studio\source\repos\opengl\opengl\game.cpp(55): note: 非常量引用只能綁定到左值 1>已完成生成項目“OpenGL.vcxproj”的操作 - 失敗。 ========== 生成: 成功 0 個,失敗 1 個,最新 0 個,跳過 0 個 ==========
先解釋左值和右值的區別:
- 從字面意思看,左右值就是在“=”兩端的變量或表達式(以前我一直是這樣理解的/手動狗頭),但其實不是這樣的。
- 左值(Location Value):並不是left_value,指的是可以尋址。指的是如果一個表達式可以引用到某一個對象,並且這個對象是一塊內存空間且可以被檢查和存儲,那么這個表達式就可以作為一個左值。
- 右值(Read Value):也就是可讀。指的是引用了一個存儲在某個內存地址里的“數據”。
例子:
void func(int &a) { cout << a; } void main() { double i = 4; func(i);//這里進行了強制類型轉換,會產生一個臨時變量
}
- 上面的寫法是不合法的,會報錯“非常量的引用只能綁定到左值”,按照正常理解 i 其實是一個左值,但是由於定義的 i 和func函數需要的參數並不是相同類型,這里實際上經過了一次強制類型轉換,並且生成了一個臨時變量(而臨時變量都是常量,不能作為左值,只能由const引用,不能改變值),所以這里非const的引用會報錯
- 這里解決方式有兩種
- 讓實參和形參類型相同,不必進行強制類型轉換
void func(int &a)
{
cout << a;
}
void main()
{
int i = 4; //修改i的類型
func(i);
}
-
- 使用右值引用
void func(const int &a)//右值引用 { cout << a; } void main() { double i = 4; func(i); }
另外,右值引用可以延長臨時變量的生命周期,比如這個例子:
int func(int a)
{ return a += 10; //函數返回值也是一個臨時變量 } void main()
{
int i = 10; const int &b = func(i); //變量a是對函數返回值(臨時變量)的引用,因此函數返回值不會在此時立即銷毀,而是一直延續到整個程序結束 cout<<b; }