右值引用是C++11引入的一种新的引用类型,使用T&&
表示。它可以绑定到右值(临时对象)上,允许对其进行修改。右值引用主要用于实现移动语义。
std::move
是一个标准库函数,用于将左值转换为右值引用,从而能够使用移动语义。
#include // std::move定义在此头文件中 MyClass obj1; MyClass obj2 = std::move(obj1); // 使用移动构造函数
std::vector
、std::string
等,在重新分配空间时,移动语义可以显著提高效率。通过使用移动语义,可以显著优化程序的性能,减少不必要的资源消耗,特别是在处理大对象或需要频繁复制的场景中。
为了支持移动语义,C++11引入了移动构造函数和移动赋值运算符。它们分别是用于移动构造对象和移动赋值对象的特殊函数。
在C++11中,引入了一个新的特性,称为“万能引用”(Universal Reference)和“折叠引用”(Reference Collapsing)。
万能引用是一个非正式的术语,用来描述可以绑定到左值和右值的引用。它们的定义依赖于上下文,主要出现在模板函数中。通常,通过类型推导的参数如果被声明为T&&,它就可能是万能引用。
template void f(T&& param); // 这个param就是万能引用 int x = 10; f(x); // T被推导为int&,所以param是int&类型 f(10); // T被推导为int,所以param是int&&类型
折叠引用是指在模板中,当类型推导产生引用到引用的情况时,C++的标准定义了一些规则来简化这些引用。这些规则确保了引用类型始终是有效的。
规则:
T& &
、T& &&
和T&& &
折叠成T&
(左值引用)。T&& &&
折叠成T&&
(右值引用)。完美转发是使用万能引用实现的一种技术,目的是在模板函数中,将传递给模板函数的参数原封不动地传递给另一个函数。为了实现这一点,标准库提供了std::forward
。
#include template void wrapper(T&& arg) { f(std::forward(arg)); // 完美转发 } void f(int& x) { std::cout << "左值引用版本\n"; } void f(int&& x) { std::cout << "右值引用版本\n"; } int main() { int a = 5; wrapper(a); // 调用左值引用版本 wrapper(5); // 调用右值引用版本 }
在这个例子中,wrapper
函数通过std::forward
将参数完美转发给函数f
,使得f
能够正确识别参数是左值还是右值。