本文将带你从最基本的概念出发,逐步深入理解 C++ 中的左值、右值、左值引用、右值引用,以及它们在现代 C++(C++11 及之后)的核心作用:移动语义与完美转发。
一、为什么要区分左值与右值?
在 C++ 中,表达式的结果(一个值)有不同的'存在方式'。有的值是可以被再次引用和修改的(比如一个变量),有的值只是临时存在的计算结果(比如 a + b)。
为了区分它们,C++ 把表达式结果分为两类:
- 左值(lvalue)
- 右值(rvalue)
这两个概念几乎贯穿了整个语言体系,也是理解'引用'、'移动语义'、'完美转发'的基础。
二、左值(Lvalue)是什么?
✅ 定义:
左值(locator value)表示在内存中有确定地址、可以被取地址 (&) 的对象。
换句话说:
左值是有名字、能被赋值的东西。
✅ 示例 1:
int x = 10; // x 是左值
x = 20; // ✅ 左值可以出现在赋值号左边
int* p = &x; // ✅ 可以取地址
在这里,x 是一个左值,因为:
- 它有名字;
- 它在内存中有一块固定的存储空间;
- 它的生命周期由程序控制。
✅ 示例 2:
模板参数推导
template <typename T>
void func(T&& arg) {
// ...
}
很多人以为这里的 T&& 永远是'右值引用',但实际上 不一定。这取决于你传入的参数是什么:

这就是所谓的 引用折叠规则(Reference Collapsing Rule):









