什么是左值、什么是右值
简单来说左值可以取地址、位于等号左边;而右值没法取地址,位于等号右边。
左值引用、右值引用
左值引用:&
能指向左值,不能指向右值。
右值引用:&&
能指向右值,不能指向左值。
int a = 5;
int &ref_a = a; // 左值引用指向左值,编译通过
int &ref_a = 5; // 左值引用指向了右值,会编译失败
const int &ref_a = 5; // 编译通过,const左值引用可以指向右值
注意:
const左值引用不会修改指向值,因此可以指向右值,这也是为什么要使用const &
作为函数参数的原因之一,如std::vector的push_back:void push_back (const value_type& val);
。如果没有const,vec.push_back(5)这样的代码就无法编译通过了。
右值引用指向左值
使用std::move
,可以将右值应用指向左值。std::move
其实就是一个强制转换如:static_cast<T&&>(lvalue)
。
int a = 5; // a是个左值
int &&ref_a_right = std::move(a);
右值引用、左值引用本身是左值
int &&ref_a_right = std::move(a);
,而ref_a_right 本身是一个左值。
总结
- 从性能上讲,左右值引用没有区别,传参使用左右值引用都可以避免拷贝。
- 右值引用可以直接指向右值,也可以通过std::move指向左值;而左值引用只能指向左值(const左值引用也能指向右值)。
- 作为函数形参时,右值引用更灵活。虽然const左值引用也可以做到左右值都接受,但它无法修改,有一定局限性。
void f(const int& n) {
n += 1; // 编译失败,const左值引用不能修改指向变量
}
void f2(int && n) {
n += 1; // ok
}
int main() {
f(5);
f2(5);
}
网友评论