C++ lvalue VS rvalue
参考这篇blog
定义
不严格的说,在C++中,左值是明确指向一块内存地址的,而右值不指向任何地方。(an lvalue is something that points to a specific memory location. On the other hand, a rvalue is something that doesn’t point anywhere.)一般右值的存在是很短暂的,而左值可以以变量的身份长时间存在。可以认为左值是一种容器,而右值是容器里的东西,要是没有容器就会消失。
比如下面这个例子:
int x = 666;
666是rvalue,只是一个字面常量(数字),没有实际的内存地址,只有程序运行起来时可能存短暂的存在于寄存器中。
而x是变量,对应着实际的内存地址,666这个rvalue是要赋值给lvalue x的
C++是要求赋值语句要求等号左边必须是lvalue,所以下面这个显然是不行的:
666 = x;
另外 & 符号可以接受一个lvalue,然后得到一个rvalue,例如下面这句是可行的, x本身是一个lvalue,但是&符号返回了这个变量所指向的内存地址,相当于是rvalue
int* y = &x; // ok
但是下面这个就不行了:
int* y = &666; // error!
因为&期待的是一个lvalue,而666是个rvalue
一个复杂点的例子
#include <iostream>
using namespace std;
class A {
public:
A(const std::string& method = "unknown"){
cout<<"in A "<<"\n";
}
void f() & { cout << "Lvalue" << endl; }
void f() && { cout << "Rvalue" << endl; }
};
void afunc(const A & a){
cout<<"get a "<<"\n";
cout<<typeid(a).name()<<"\n";
A().f();
cout<<endl;
}
void afunc2(A & a){
cout<<"get in a2"<<"\n";
cout<<typeid(a).name()<<"\n";
A().f();
a.f();
cout<<endl;
}
int main()
{
cout << "Hello World";
A a;
afunc2(a);
afunc2(A());// error: cannot bind non-const lvalue reference of type ‘A&’ to an rvalue of type ‘A’
afunc(A());
return 0;
}
可以看到那行报错信息:
afunc2(A());
// error: cannot bind non-const lvalue reference of type ‘A&’
//to an rvalue of type ‘A’
传入的A()是一个rvalue,而预先声明的A a;是一个变量,是一个lvalue,所以会出现问题
这里两个函数都是传递的A的引用,但加了const之后是不能修改的,参数里的a只是实际传入的对象的别称