Every C++ expression has a type, and belongs to a value category.
左值右值都是表达式属性,该属性称为value category.
在现代C++中,对于左值表达式,通过具体名字和引用来指定一个对象,非左值就是右值。
左值表示程序中必须有一个特定的名字引用到这个值。
An lvalue has an address that your program can access. Examples of lvalue expressions include variable names, including const variables, array elements, function calls that return an lvalue reference, bit-fields, unions, and class members.
右值表示程序中没有一个特定的名字引用到这个值。
区分区分表达式的左右值属性一个简便方法:若可对表达式用 & 符取址,则为左值,否则为右值。
举例:
int x = 0; ++x; // lvalue x++; // rvalue
++x修改自身值,并返回自身;x++先创建一个临时变量,为其赋值,而后修改x的值,最后返回临时对象。
int x = 0; ++++x; // ok x++++; // 报错
前++是直接对对象自增后返回对象,而后++会先返回记录当前值,再自增,最后返回一个无名的临时对象,那么x++++就是让第一个后++返回的无名临时对象再自增,这样对C++是无意义的,所以这样就无法编译通过。
引用Type& :只能绑定到可修改的左值表达式
const Type& : 可以绑定到任何表达式
Type&&:可绑定到可修改的左值或右值表达式
const Type&&:可绑定到任何表达式
Error:non-const lvalue reference cannot bind to a temporaryvoid swap(int& a, int& b) { // ... } int main() { int a = 10; int b = 5; swap(a + 1, b + a); }
执行上述代码会报如下错误:
Error : non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'
调用swap函数时,a+1和a+b的值会存在一个临时变量中,当把这两个临时变量传递给swap时,由于swap的参数是int &,不是常量引用,因此会产生编译错误。
错误原因:
变量a在内存中有确切的地址,变量b在内存中也有确切的地址,但是a+b却没有,a+b不是左值(a+1也不是),只是临时计算一下,然后将得出的结果用于其他语句,之后空间就被释放了,如果绑定一个非const引用到a+b相当于一个野指针(引用的本质是一个指针常量),所以是不允许的。
临时变量不能作为非const引用参数,是C++编译器的一个关于语义的限制。如果一个参数是以非const引用传入,C++编译器就有理由认为程序员会在函数中修改这个值,并且这个被修改的引用在函数返回后要发挥作用。但如果把一个临时变量当作非const引用参数传进来,由于临时变量的特殊性,程序员并不能 *** 作临时变量,而且临时变量随时可能被释放掉,所以,一般说来,修改一个临时变量是毫无意义的,据此,C++编译器加入了临时变量不能作为非const引用的这个语义限制,意在限制这个非常规用法的潜在错误。
解决方案:
void swap(const int& a, const int& b) { // ... } int main() { int a = 10; int b = 5; swap(a + 1, b + a); }
将普通引用改为常量引用,改为常量引用后不能修改绑定的对象,只能读不能写。
assigning a temporary object to the const reference extends the lifetime of this object to the lifetime of the const reference
为什么此方案可行?因为常量引用会延长临时变量的生命周期!
ReferenceLvalues and Rvalues(C++)左值(lvalues)和右值(rvalues)表达式左值右值(C++学习)C++沉思录:x+y不是左值,不能绑定一个非const引用到自身C++中临时变量不能作为非const的引用参数的方法C++ non-const lvalue reference cannot bind to a temporaryC++之error: cannot bind non-const lvalue reference of type ‘myString&’ to an rvalue of type ‘myString’
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)