本文章属于专栏- 概述 -《业界C++进阶建议整理》-CSDN博客
继续上篇《Effective Modern C++》- 极精简版 22-29条。本文列出《Effective Modern C++》的30-35条的个人理解的极精简版本。
- Item30、熟悉完美转发失败的情况
- 完美转发(perfect forwarding)意味着我们不仅转发对象,我们还转发显著的特征:它们的类型,是左值还是右值,是const还是volatile
- 当模板类型推导失败或者推导出错误类型,完美转发会失败。
- 导致完美转发失败的实参种类有花括号初始化,作为空指针的0或者NULL,仅有声明的整型static const数据成员,模板和重载函数的名字,位域。
- 个人理解:除了仅有声明的整型static const数据成员失败是在链接的时候报错,其他均是在编译时报错。所以这些错误都不会延迟到运行期间出现问题,所以记住这些规则的作用是提高开发效率,而对于这块规则低频使用的人,在使用中学习也来得及。
- 完美转发(perfect forwarding)意味着我们不仅转发对象,我们还转发显著的特征:它们的类型,是左值还是右值,是const还是volatile
- Item31、避免使用默认捕获模式
- 默认的按引用捕获可能会导致悬空引用。
- 默认的按值捕获对于悬空指针很敏感(尤其是this指针),并且它会误导人产生lambda是独立的想法。
- 个人理解:核心是默认捕获的规则,没有那么显而易见,所以用户请指明
- Item32、使用初始化捕获来移动对象到闭包中
- c++14的特性,可以在捕获时使用std::move,将局部对象移动到lambda中
-
auto lambda = [data = std::move(data)]() mutable { };
-
- c++14的特性,可以在捕获时使用std::move,将局部对象移动到lambda中
- Item33、对auto&&形参使用decltype以std::forward它们
-
auto f = // c++14中才支持lambda被auto修饰 [](auto&& param) { return func(normalize(std::forward<decltype(param)>(param))); };
-
- Item34、考虑lambda而非std::bind(即使是c++11)
- 优先lambda而不是std::bind的最重要原因是lambda更易读,以及性能稍有优势。如
-
auto bound_print = std::bind(print, std::placeholders::_1, "Hello, Bind!"); auto lambda_print = [](int i) { print(i, "Hello, Lambda!"); };
- Item35、优先考虑基于任务的编程而非基于线程的编程
- 硬件线程:现代计算机体系结构为每个CPU核心提供一个或者多个硬件线程。
- 软件线程:操作系统管理的在硬件线程上执行的线程。
- std::thread :是C++执行过程的对象,并作为软件线程的句柄(handle)
- 个人理解:基于std::future,是将异步任务的调度交给c++标准库的开发者。通用的同时意味着部分场景的低效,对于追求性能极致的应用(资源使用得多的应用),需要自己去使用非常基础的线程的API