问题现象描述
临时实例赋值给非常量引用,会警告: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));
}
本文结束。