《Modern Effective C++》学习笔记6 lambda表达式

条款三十一:避免默认捕获模式

捕获只能针对与在创建lambda表达式的作用域内可见的非静态局部变量(包括形参),然而实测发现静态局部变量也是可以捕获的。

默认按引用捕获模式的缺陷:

  1. lambda表达式的生存周期可能会大于默认捕获的局部变量或形参的生存周期,导致无效引用,而显式列出捕获对象可以起到提醒声明周期的作用,降低出错概率;

默认按值捕获模式的缺陷:

  1. 捕获裸指针时获得的只是一个裸指针副本,其他地方可能会delete这个指针,比如this指针;

  2. 按值捕获只能获得捕获当时的值的副本,不能感知到捕获内容在闭包之外的更新;

 int num = 1;
 auto calc = [=](int value) {
   cout << value + num << “ ”;
 };
 ​
 for(int i = 0; i < 5; ++i) {
   calc(i);
   ++num;
 }
 ​
 // 输出 1 2 3 4 5

条款三十二:使用初始化捕获将对象移入闭包

C++14支持通过初始化捕获(广义lambda捕获)将对象移入闭包,见下面代码:

 // C++14
 void test2() {
   std::vector<double> data(2, 1.0);
 ​
   auto func = [data = std::move(data)]() {
     cout << data[0] << endl;
   };
 ​
   func();
 }
 ​
 // C++11
 void test3() {
   std::vector<double> data(2, 2.0);
 ​
   auto func = std::bind(
     [](const std::vector<double>& data) {
       cout << data[0] << endl;
     }, 
     std::move(data)
   );
 ​
   func();
 }

条款三十三:对auto&&型别的形参使用decltype,以std::forward之

其实就是用forward+decltype来实现auto&&类型的转发,见下面代码:

 auto f = 
   [](auto&& param) {
     return func(normalize(std::forward<decltype(param)>(param)))
   };
 // 可变长形参
 auto f = 
   [](auto&&... param) {
     return func(normalize(std::forward<decltype(param)>(param)...))
   };

条款三十四:优先使用lambda表达式,而非std::bind

lambda表达式比起使用std::bind而言,可读性更好,表达力更强,可能运行效率也更高。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值