- void f4(const std::unique_ptr<int>& t) {
- // 左值匹配该函数
- printf("const std::unique_ptr
&\n" ); - }
-
- void f4(std::unique_ptr<int>&& t) {
- // 右值匹配该函数
- printf("std::unique_ptr
&&\n" ); - }
-
- void f4(const std::shared_ptr<int>& t) {
- // 左值匹配该函数
- printf("const std::shared_ptr
&\n" ); - }
-
- void f4(std::shared_ptr<int>&& t) {
- // 右值匹配该函数
- printf("std::shared_ptr
&&\n" ); - }
-
- template <class T>
- void f3(T&& t) {
- // t为模板参数,不知道传入的是左值还是右值,需要使用forward转发参数给f4
- f4(std::forward
(t)); - }
-
- template <class T>
- void f2(T&& t) {
- // t为模板参数,不知道传入的是左值还是右值,捕获t的时候需要使用forward
- [t1 = std::forward
(t)]() mutable { - // 增加mutable属性是为了让捕获的参数可修改,此时t1的类型为T
- // 如果删除mutable属性,此时t1的类型为const T,使用move是无任何效果的
- // 使用std::move将t1强制转换成右值传递给f3(注意:如果没有mutable属性,虽然使用了std::move,但是传递给f3的还是左值)
- f3(std::move(t1));
- }();
- }
-
- template <class T>
- void f1(T&& t) {
- // t为模板参数,不知道传入的是左值还是右值,需要使用forward转发参数给f2
- f2(std::forward
(t)); - }
-
- int main() {
- auto p = std::make_unique<int>(100);
- f1(std::move(p));
- assert(!p);
-
- auto p1 = std::make_shared<int>(200);
- f1(p1);
- assert(p1);
- f1(std::move(p1));
- assert(!p1);
-
- // 在有mutable属性的时候输出如下:
- // std::unique_ptr
&& - // std::shared_ptr
&& - // std::shared_ptr
&& -
- // 在没有有mutable属性的时候输出如下:
- // const std::unique_ptr
& - // const std::shared_ptr
& - // const std::shared_ptr
& -
- system("pause");
- }
真正理解到了右值引用、引用折叠、变量生命周期就很容易明白什么时候使用std::move,什么时候使用std::forward。