左值和右值
本文整理自网文,如有冒犯,请告知删除。
左值(lvalue)和右值(rvalue)
左值(lvalue)和右值(rvalue)是c/c++中的基础概念。 简单理解为:有名字的是左值,没有名字的是右值。
- C
- C语言中,左、右值均可为变量或表达式
- C语言中,左值可出现在=号左边,也可出现在=号右边
- C语言中,右值只能出现在=号右边
int x, y;
x = 1;
y = 2;
x = y;
y = x;
2 = x; //err
x,y为左值,2为右值
- CPP
- CPP语言中,一个表达式会产生一个左值,或者一个右值,前者称为左值表达式,后者称为右值表达式。
- CPP语言中,对于基本类型,左值和右值概念与C语言相同。
- CPP语言中,对于自定义类型,右值允许通过它的成员函数进行修改。
class A {
public:
A(int i) : _i(i) {}
A& operator=(const A& other) {
_i = other._i;
return *this;
}
void set(int i) {
_i = i;
}
int get() {
return _i;
}
private:
int _i;
};
int main() {
A a(5);
auto f = [&] () ->A {
return a;
}
f().set(10); //rvalue modify self.
return 0;
}
- 左值引用,右值引用
-
左值引用:就是对左值进行引用
-
右值引用:就是对右值进行引用
-
引用只是变量的别名,本身不绑定内存。
-
引用定义必须立即初始化。
-
左值引用是具名变量值的别名,而右值引用则是不具名(匿名)变量的别名。
-
左值引用通常也不能绑定到右值,但常量左值引用是个“万能”的引用类型。
-
非常量左值只能接受非常量左值对其进行初始化。
int &a = 2; // 左值引用绑定到右值,编译失败
int b = 2; // 非常量左值
const int &c = b; // 常量左值引用绑定到非常量左值,编译通过
const int d = 2; // 常量左值
const int &e = c; // 常量左值引用绑定到常量左值,编译通过
const int &b =2; // 常量左值引用绑定到右值,编程通过
右值值引用通常不能绑定到任何的左值,要想绑定一个左值到右值引用,通常需要std::move()将左值强制转换为右值,例如:
int a;
int &&r1 = c; // 编译失败
int &&r2 = std::move(a); // 编译通过
右值两个特性: 可以调用成员函数。 只能被 const reference 指向。