C++完美转发

1 万能引用与引用折叠

万能引用:T&&auto&&

需要注意的是不能在已经确定T类型的情况下,如"func()"这种形式下无法使用万能引用

引用叠加推导规则(引用折叠):

类模板型T实际类型最终类型
T&RR&
T&R&R&
T&R&&R&
T&&RR&&
T&&R&R&
T&&R&&R&&

从上面可看出只要左值参与进来,最后推导的结果就是一个左值引用:

为了避免不必要的复制,我们可以使用引用作为参数:

这时候我的get_string()返回的是一个右值,如果想让normal_forwarding()既能接受左值又能接受右值在以前是这样干的:

但是这么做就不能更改传入t的值了,因为它前面加了const修饰,在了解万能引用后可以这样干:

由于这里会根据传入参数(左值或右值)不同给show_type,它的参数类型可以自动在传入参数的时候推导出来,用T表示即可,因此可改为:

在此基础上main()中的这一行:

实际上传入的是一个左值,那如果想在传入左值让show_type()收到的参数也是左值,我们在normal_forwarding()中使用static_cast<T&&>将T转换为右值引用,这样无论t实际是什么类型的引用,根据引用折叠规则t总是能被解析成它本身的引用类型:

举个例子,在t是左值引用的前提下,根据上面引用折叠的表我们可以得到左值引用在引用折叠后得到的还是一个左值引用,同理,main()这一行:

传入的是一个右值引用,右值引用字引用折叠后得到的还是一个右值引用

2 完美转发

std库中提供了forward()函数,具体代码如下:

其中我们可以用forward()去代替static_cast<T &&>,可以写成:

这里涉及的remove_reference实现了上面的引用折叠,在打开type_traits.h文件可以看到以下定义:

测试引用折叠&万能引用:

完美转发的例子: