4.理解函数模板类型推断与查看类型推断结果
4.1 引用折叠规则
通过对前面几节的学习,读者对万能引用的概念已经掌握了。若一个函数模板的参数类型是万能引用,传递左值和右值给该函数模板时,编译器推断出来模板参数类型。回顾一下:
可以看到,如果传递左值进去,编译器给T(是T不是tmprv)推断出来的是int&类型;如果传递右值进去,编译器给T(是T不是tmprv)推断出来的是int类型。
这里比较让人费解的是“myfunc(i);”,根据现在的观察,编译器给推断出来的T类型是int&,那自己可以拿这个int&去手工实例化一下myfunc看看是啥结果。
这里模拟编译器去实例化一下。很简单,直接用int&替换T就可以了,得到了下面这个结果。
通过观察发现了三个&挨在了一起。初次看上去可能让人费解。这里可以把这三个&分成两组,左边这个&是属于和左边的int一组的(T),右边这两个&&是和tmprv一组的(这两个&&是属于tmprv的),既然是两组,这里可以把它们中间加上空格,方便观察:
编译器合并&时有个合并规则:
左值引用是一个&表示,右值引用是两个&&表示,所以这两种引用组合一下就会有四种可能的组合:
· 左值-左值& - &
· 左值-右值& - && (这是上面范例当前的情形)
· 右值-左值&&-&
· 右值-右值&&-&&
那么,引用折叠的规则就是:如果任意一个引用为左值引用,结果就为左值引用(左值引用会传染),否则结果为右值引用。所以,上面这四种情形的组合结果就是:
· 左值引用&
· 左值引用&
· 左值引用&
· 右值引用&&
所以,最终:
4.2 转发与完美转发
4.3 std::forward
4.4 std::move和std::forward的区别
4.5 再谈万能引用