看源码时,浅显的理解,暂时记录。有错误指出,有好文章推给我瞅瞅
左值、右值定义
左值(lvalue):
- 左值是可以标识内存位置的表达式。
- 左值可以位于赋值语句的左侧或右侧。
- 左值通常代表具名变量、对象、数组元素、引用等。
- 通过左值可以修改变量的值。
- 示例:
int x = 42;
,int* ptr = &x;
,int arr[5];
。
右值(rvalue):
- 右值是不能标识内存位置的表达式,通常是临时的、一次性的值。
- 右值通常出现在赋值语句的右侧。
- 右值可以是字面常量、临时对象、表达式的结果等。
- 通过右值通常不能修改变量的值。
- 示例:
int y = 5 + 3;
,std::string("hello")
,std::move(x)
。
C++11 引入了 右值引用(rvalue reference)
的概念,允许程序员更好地处理右值。右值引用的引入使得可以实现移动语义,即将资源的所有权从一个对象转移到另一个对象,从而提高了性能。 因此一般把左右值的情况分开处理,对右值采用std::move()
进行优化
完美转发
当使用左值引用、右值引用和完美转发时,通常会涉及 函数重载
和 std::forward
的使用。示例如下:
#include <iostream>
#include <utility>
// 左值版本
void ProcessValue(int& x)
{
std::cout << "Processing lvalue: " << x << std::endl;
}
// 右值版本
void ProcessValue(int&& x)
{
std::cout << "Processing rvalue: " << x << std::endl;
}
// 模板函数,使用完美转发
template <typename T>
void ForwardAndProcess(T&& x)
{
ProcessValue(std::forward<T>(x));
}
int main()
{
int a = 42;
ForwardAndProcess(a); // 调用左值版本
ForwardAndProcess(123); // 调用右值版本
return 0;
}
在这个示例中,有三个函数:
ProcessValue()
函数有两版本,一个接受左值引用int&
,另一个接受右值引用int&&
。T&&
,这是通用引用,可以接收左值,也可以接收右值std::forward<T>()
,确保将参数以原始的值类别传递给下游函数。ForwardAndProcess
是一个模板函数(负责转发),使用完美转发来接受任何类型的参数T&&
,然后将其传递给 ProcessValue 函数,保持参数的值类别。这样,它能够正确地调用 ProcessValue 的左值或右值版本。