【C++】完美转发

  • 973 字
  1. 1. 完美转发
    1. 1.1. std::forward

完美转发

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
using namespace std;
void f(const string& s){
cout <<"左值:"<<s<<endl;
}
void f(string&& s){
cout <<"右值"<<s<<endl;
}

void g(const string& s){
f(s);
}
void g(string&& s){
f(s);
}

int main(){
// 右值
g(string("hello1"));

// 左值
string s1("hello2");
g(s1);
}

这段代码,我们希望让右值调用右值的重载函数f,左值调用左值的重载函数f,但最后结果均调用了左值重载函数

这是因为在函数g中,s本身是一个局部变量,拥有地址,是一个左值

这时候我们需要进行类型转换

std::forward

我们当然可以使用static_cast<>()来进行转换,但是这里可以使用forward<>()函数进行转换,结合函数模板,使得代码更加方便易读

1
2
3
4
template<class T>
void g(T&& s){
f(forward<T>(s));
}

这里在形参列表中的T&& s被称为万能引用或转发引用

它既可以绑定左值也可以绑定右值,会在实例化时根据传入参数类型自动推导成对应类型

T的类型取决于传入的是左值还是右值

  • 左值:T被推导为实参类型的引用
  • 右值:T被推导为实参类型的非引用

forward函数实现了一个类型转换

  • 若传入实参是右值,则forward函数会返回一个右值引用
  • 若传入实参是左值,则函数模板T会被替换为该类型的引用,但此时会出现引用的引用(&&&),这时遵循引用折叠规则,得到类型的左值引用

即除了右值引用的右值引用被折叠为右值引用外,其余的只要有左值引用,就会被折叠为左值引用

赞助喵
非常感谢您的喜欢!
赞助喵