std::forward的神秘面纱

本文通过示例详细解析C++中的右值引用、引用折叠以及模板中的std::forward和std::move的使用,阐述它们在智能指针传递中的作用,以及如何影响变量生命周期。理解这些概念对于提升C++编程技能至关重要。
摘要由CSDN通过智能技术生成
void f4(const std::unique_ptr<int>& t) {
  // 左值匹配该函数
  printf("const std::unique_ptr<int>&\n");
}

void f4(std::unique_ptr<int>&& t) {
  // 右值匹配该函数
  printf("std::unique_ptr<int>&&\n");
}

void f4(const std::shared_ptr<int>& t) {
  // 左值匹配该函数
  printf("const std::shared_ptr<int>&\n");
}

void f4(std::shared_ptr<int>&& t) {
  // 右值匹配该函数
  printf("std::shared_ptr<int>&&\n");
}

template <class T>
void f3(T&& t) {
  // t为模板参数,不知道传入的是左值还是右值,需要使用forward转发参数给f4
  f4(std::forward<T>(t));
}

template <class T>
void f2(T&& t) {
  // t为模板参数,不知道传入的是左值还是右值,捕获t的时候需要使用forward
  [t1 = std::forward<T>(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>(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<int>&&
  // std::shared_ptr<int>&&
  // std::shared_ptr<int>&&

  // 在没有有mutable属性的时候输出如下:
  // const std::unique_ptr<int>&
  // const std::shared_ptr<int>&
  // const std::shared_ptr<int>&

  system("pause");
}

真正理解到了右值引用、引用折叠、变量生命周期就很容易明白什么时候使用std::move,什么时候使用std::forward。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值