万能引用和完美转发
#模板元编程
2025-03-16
万能引用
万能引用是 C++11
引入的一种特殊引用类型,其语法形式是
T&&,但只有在模板参数推导时,才能成为万能引用。
显式类型不会触发万能引用。
特点:
- 左值可以匹配
T&,右值匹配T&& - 类型推导时,
T可能是U&(左值)或U(右值)
1 | |
完美转发
完美转发是指保持参数原始的左值/右值属性,将其传递给另一个函数。它主要依赖
std::forward。
1 | |
remove_reference
适用于非引用类型,如
int、double、std::string 等。
type 直接定义为 _Tp,即保持原类型不变。
1 | |
适用于左值引用 T&,它将
T& 去掉引用,变为 T。
1 | |
适用于右值引用 T&&,它将
T&& 去掉引用,变为
T。
1 | |
forward 源码
1 | |
接受左值版本:
typename std::remove_reference<_Tp>::type& __t表示把接受到的参数的引用去除得到原始类型 T,原始类型 T 再加上后面的 &,成为左值引用 T&,故而接受左值,称为左值版本- 强转为
_Tp&&(右值引用),并返回
由于 _TP 是 T&,那么替换过来 T& && --> T&,确保传进来是左值,传出去还是左值。
接受右值版本:
typename std::remove_reference<_Tp>::type&& __t表示把接受到的参数的引用去除得到原始类型 T,原始类型 T 再加上后面的 &&,成为右值引用 T&&,故而接受右值,称为右值版本- 断言判断防止传递左值,只接受右值
- 强转为
_Tp&&(右值引用),并返回
由于 _TP 是 T&&,那么替换过来 T&& && --> T&&,确保传进来是右值,传出去还是右值。
move 源码
1 | |
- _Tp 是泛型参数,可以接受左值或右值
- 先用
std::remove_reference去掉 _Tp 的引用,再加上 &&,使其变成右值引用 - 使用
static_cast强制转换__t为右值引用。
std::move
总是转换为右值,不会区分原本是左值还是右值。