Skip to the content.

《Effective Modern C++》规则速览

Scott Meyers 的《Effective Modern C++》总结了有效使用 C++11 和 C++14 的 42 个具体做法。书中的 “universal reference” 在后来的标准术语中通常称为“转发引用(forwarding reference)”。

一、类型推导

  1. 理解模板的类型推导规则。
  2. 理解 auto 的类型推导规则。
  3. 理解 decltype。 // FIXME
  4. 掌握查看类型推导结果的方法。

二、auto

  1. 优先使用 auto,而不是显式类型声明。
  2. 当 auto 推导出非预期类型时,使用显式类型初始化惯用法。

三、转向现代 C++

  1. 创建对象时,区分 () 和 {}。
  2. 优先使用 nullptr,而不是 0 或 NULL。
  3. 优先使用别名声明 using,而不是 typedef。
  4. 优先使用有作用域的 enum class,而不是无作用域枚举。
  5. 优先使用删除函数 = delete,而不是只声明为 private 却不定义的函数。
  6. 重写虚函数时使用 override。
  7. 优先使用 const_iterator,而不是 iterator。
  8. 不会抛出异常的函数应声明为 noexcept。
  9. 尽可能使用 constexpr。
  10. 让 const 成员函数具备线程安全性。
  11. 理解特殊成员函数的自动生成规则。

四、智能指针

  1. 使用 std::unique_ptr 管理独占所有权的资源。
  2. 使用 std::shared_ptr 管理共享所有权的资源。
  3. 使用 std::weak_ptr 表示可能失效、但不参与共享所有权的观察关系。
  4. 优先使用 std::make_unique 和 std::make_shared,而不是直接使用 new。
  5. 使用 Pimpl 惯用法时,在实现文件中定义特殊成员函数。

五、右值引用、移动语义与完美转发

  1. 理解 std::move 和 std::forward 的作用。
  2. 区分转发引用和右值引用。
  3. 对右值引用使用 std::move,对转发引用使用 std::forward。
  4. 避免对转发引用进行函数重载。
  5. 熟悉替代转发引用重载的方法,如标签分派、约束模板和按值传递。
  6. 理解引用折叠。
  7. 假定移动操作可能不存在、成本不一定低,也不一定会被调用。
  8. 熟悉完美转发失效的场景。

六、Lambda 表达式

  1. 避免使用默认捕获模式。
  2. 使用初始化捕获将对象移动到闭包中。
  3. 对 auto&& 参数使用 decltype 和 std::forward 进行转发。
  4. 优先使用 Lambda,而不是 std::bind。

七、并发 API

  1. 优先采用基于任务的编程方式,而不是直接操作线程。
  2. 必须异步执行时,为 std::async 指定 std::launch::async。
  3. 确保 std::thread 在所有执行路径上都变为不可联结状态。
  4. 注意不同线程句柄的析构行为并不相同。
  5. 考虑使用 void 类型的 future 实现一次性事件通知。
  6. 并发编程使用 std::atomic,访问特殊内存才使用 volatile。

八、细节调整

  1. 对于总会被复制、可复制且移动成本低的参数,考虑按值传递。
  2. 考虑使用 emplace,而不是 insert 或 push;但应注意隐式转换和资源所有权问题。

阅读提示

human

chapter 5 : 右值引用,移动语义,完美转发

移动语义让创建 move only 类型的对象成为可能,包括 std::unique_ptr, std::future, std::thread.

形参是 左值, 即使其类型是右值引用。

void f(Widget && a);

本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。