万能引用和完美转发
#模板元编程
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
总是转换为右值,不会区分原本是左值还是右值。