这里是《C++ Tempaltes 2th》的读书笔记
万能引用(Universal Reference)
在模板中,存在一种万能引用模板,其参数是T&&
:
|
|
这种引用时可以同时接收左值和右值引用的(不像T&
只能接受左值引用):
|
|
当传入一个右值/右值引用时,它会将其推导为对应的引用。
|
|
注意这里T
的推导:被推导为int&或const int&
而不是int或const int
!
这个规则在转发函数参数时会造成问题:
|
|
这个时候,无论t是T
还是T&
,t都会被视为T&
,都会调用左值引用的foo函数(第一个函数)。
完美转发
要解决如上的参数转发问题,必须要使用完美转发。
完美转发会保留变量原本的特性:
- 可变变量转发后仍然可变
- const变量转发后仍然为const
- 可移动对象转发后仍然是可移动的
完美转发就一个函数:std::forward()
,我们需要这么用:
|
|
使用万能引用的麻烦
使用万能引用的时候,T
会被视为T&
,这意味着你没办法在函数体内声明非引用变量:
|
|
这里由于T会被推断为int&
,所以这里x的声明是错误的。
std::move
std::move
说白了就是一个类似于static_cast
的强制类型转换,它会将所有的类型强转到右值引用。但是其本身不会进行移动操作。
注意以下代码:
|
|
这里[1]
将会调用String
的拷贝构造函数,这毋庸置疑。
但是[2]
同时也会调用拷贝构造函数。记住,std::move
只是将类型强转为右值引用,这意味着其会保留const
标识,也就是说[2]
中经过std::move
之后的类型为const String&&
,这类型和移动构造函数的类型不符,所以会调用拷贝构造函数。
std::move和std::forward的区别
他们两个本质上都是强制类型转换,只不过std::move
无条件转换,而std::forward
是只有参数为右值引用的时候才会转换。