問題現象描述
臨時實例賦值給非常量引用,會警告:warning C4239: 使用了非標準擴展:“參數”,原因是:“非常量引用只能綁定到左值”。
例如下面例子:
struct B {
B(int ti) {}
};
struct A {
A() {};
A(B &other) { }
};
void func(void) {
A cobj(B(123)); // 會警告:非常量引用只能綁定到左值
}
原理分析
引用的本質是某對象的影子副本,操作引用就相當於操作某對象本身,引用實現本質就是一個指針,這個指針需要指向一個實在能拿到地址的對象,否則就沒有意義。
例如:int &i = 8; 如果執行 i=2;,那根本不知道去修改誰,因爲“8”不是可以指向的變量實例,也就是此時的引用“i”是沒意義的。
不僅如此,如果非常量刑引用和臨時變量捆綁,編譯器也會警告,因爲程序後續的操作,實際修改的是臨時變量,編譯器認爲如此操作是有風險或者不符合程序員本意需要。
回到上面提的例子中的“A cobj(B(123))”,此時的“B(123)”就是一個臨時變量,它要被當作“B &”調用A的構造函數,相當於先建立一個 把“B(123)”臨時變量賦給"B&"變量,所以編譯器就發出警告。
如果程序員瞭解這個細節,其實可以不管這個警告,只需關閉這個警告就行。
修改辦法
修改辦法很多,可以改爲不賦值給引用,或者額外定義個變量來賦給引用就行。
例如上面例子修改:
void func(void) {
B tmpb(123);
A cobj(tmpb);
}
或者這樣(程序員務必瞭解如此是否符合自己的業務需要):
struct B {
B(int ti) {}
};
struct A {
A() {};
A(B other) { } // 構造時候不用引用
};
void func(void) {
A cobj(B(123));
}
本文結束。