不要假装努力,结果不会陪你演戏。
文章目录
- 完美转发的使用场景
- 完美转发
完美转发的使用场景
请看下面的这个代码
#include<iostream>
using namespace std;
void func(int&& t)
{cout<<"int&&"<<endl;return;
}
void func(int& t)
{cout<<"int&"<<endl;
}
int main()
{int a=10;int b=20;int&& t=a+b;func(t);return 0;
}
我们可以想一下这个代码打印出来的结果是什么样子?
这个结果可能会跟我们想像的有些差距这里我请大家想一个问题就是我们用右值引用t=a+b那么这个右值引用t到底是一个右值还是左值,其实在面对这一点的时候c++委员会也陷入了纠结,但是最终还是设置为左值,这是为什么呢,因为我们可以想一下如果我们传递过去是一个右值引用的话我们的赋值的时候右值是不能被赋值的,因此在这里c++委员会将右值转会为了左值,可是在实际开发场景中我们有些时候是需要它保留右值特性的,那么这时候需要我们怎么办呢,这也就是完美转发被发明的意义。
完美转发
通过上面的赘述我们可以知道其实完美转发就是在传参的时候保留原有参数的类型属性,那么我们将上面的那个代码改一下
#include<iostream>
using namespace std;
void func(int&& t)
{cout<<"int&&"<<endl;return;
}
void func(int& t)
{cout<<"int&"<<endl;
}
int main()
{int a=10;int b=20;int&& t=a+b;func(forward(t));//完美转发return 0;
}
那么将代码改为上面 那个样子我们的打印结果就可以变为我们想要的场景了那么完美转发在实际开发过程中的使用场景有什么呢?首先就比如说我们的模拟实现链表的push_back(“111”)这个时候这个111很明显用右值引用去接受更为方便。这里我们模拟实现一小部分代码
void push_back(string &&a)
{
insert(_head->next,forward<string>(a);
}
void insert(Node*pos,T&&a)
{
Node*prev=pos->_prev;
Node*newnode=new Node;
newnode->_data=std::forward<string>(a);prev->_nex=newnode;
newnode->_prev=prev;
newnode->_next=pos;
pos->_prev=newnode;
}
好的那么上面就是我们完美转发的一个实际用途,完美转发在我们日常生活中的使用也是非常便捷的它可以保留我们传递参数的原有属性。