完美转发(右值引用)
阅读本文建议搭配:什么是 + 为什么要用 右值引用。
文章目录
1. 定义
完美转发:目标函数将参数按照传递给转发函数的实际类型转给目标函数,而不产生额外的开销。
即:参数为左值,转发左值,参数为右值,转发右值。左值会调用拷贝语义,右值会调用移动语义。
右值引用会在第二个之后的参数传递过程中属性丢失。C++11通过forward函数来实现完美转发。
2. 用法
首先看这一段函数:
template<typename T1>
void func1(T1) {
cout << sizeof(T1) << endl;
}
int main() {
int i = 10;
int a[100] = {i};
int *p = a;
func1(i); // 4
func1(a); // 8
func1(p); // 8
exit(0);
}
数组在作为参数传递到函数内部后,将会被转换为指针类型,因此func1(a)
的输出值为8
。(这里解释一下为什么void func1(T1)
,而不是void func1(T1 t1)
,其实后者也可以,如果不写参数名,那么函数内部就不能使用该形参了,这里我只需要获取类型就行,并不需要具体参数名,因此就没写。)
如何保持a的数组类型不变呢(目标函数将参数按照传递给转发函数的实际类型转给目标函数,而不产生额外的开销)?—— 使用引用。左值引用 / 右值引用。👇
// g++ cha1.cpp -o cha1
// ./cha1
#include <bits/stdc++.h>
using namespace std;
template<typename T1>
void func1(T1) {
cout << sizeof(T1) << endl;
}
template<typename T2>
void func2(T2 &) {
cout << sizeof(T2) << endl;
}
template<typename T3>
void func3(T3 &&) {
cout << sizeof(T3) << endl;
}
int main() {
int i = 10;
int a[100] = {i};
int *p = a;
func1(i); // 4
func1(a); // 8
func1(p); // 8
func2(i); // 4
func2(a); // 400
func2(p); // 8
func3(i); // 4
func3(a); // 400
func3(p); // 8
exit(0);
}