EffectiveModernC++
  右值引用,移动语义和完美转发
    Item 23: 理解`std::move`和`std::forward`
      美好愿景
        移动代替昂贵的复制操作
        完美转发接收任意数量参数的函数模板称为可能
      故事梗概
        Move 就是无条件转化value为 rvalue
        Forward就是有条件转化 value为rvalue
      关于move语义的理解
https://stackoverflow.com/questions/36827900/what-makes-moving-objects-faster-than-copying
    Item 24: 区分通用引用和右值引用
      通用引用看起来就是模板中的&&
    Item 25: 对右值引用使用`std::move`，对通用引用使用`std::forward`
    Item 26: 避免在通用引用上重载
      会导致滥用
    Item 27: 熟悉通用引用重载的替代方法
    Item 28: 理解引用折叠
    Item 29: 假如移动操作并不像传说的那样快捷
      不要滥用移动
    Item 30: 熟悉完美转发会失败的情况
  Lambda表达式
    Item 31: 避免使用默认捕获模式
    Item 32: 使用初始化捕获移动对象到闭包中
    Item 33: 对于std::forward的auto&&形参使用decltype
    Item 34: 优先使用lambda而不是`std::bind`
  并发API
    Item 35: 优先基于任务编程而不是基于线程
      async是更高层的抽象
      thread如果有资源超载，需要自己解决负载均衡问题
    Item 36: 确保必须是异步时，指定`std::launch::async`
      使用async的策略选择以及默认策略
    Item 37: 确保线程最终在执行结束后unjoinable
      通常在对象的析构函数中实现
    Item 38: 关注不同线程句柄的析构行为
      thread和future表现不同
        `std::shared_future`会使得future被引用，存在对个引用副本，要最终删除类似智能指针
    Item 39: 对于一次性通信事件考虑使用无返回future
      如何以挂起状态开启一个线程
    这里还需要参考另一本使用C++并发编程这本书
    Item 40: 关于`std::atomic`使用以及volatile
      volatile
      volatile，mutable和const
        mutable只能对类成员变量使用
        volatile更多的是抑制编译器进行寄存器优化，每次都从内存取值
  补充
    Item 41: 如果参数可拷贝并且移动开销很低,总是考虑按值传参
      标题已经清楚表明了观点
      基类与派生类按值传递的切片问题
    Item 42: 考虑使用emplacement代替insertion
      值被直接构造到容器中，而不是直接赋值（省略临时对象的构造和析构）
      传入类型与容器类型不一致（就会直接构造，而不是临时变量对其类型）
      容器不拒绝已经存在的值
  智能指针
    Item 18: 对于独占资源使用`unique_ptr`
    Item 19: 对于共享资源使用`std::shared_ptr`
    Item 20: 像`std::shared_ptr`使用`std::weak_ptr`会造成dangle
    Item 21: 优先使用`std::make_unique`和`std::make_shared`而不是直接使用`new`
    Item 22: 当使用Pimpl惯用法，请在实现中定义特殊成员函数
      这是减少类实现与类使用者之间编译依赖的一种技术
      `std::unique_ptr`的要求，shared的没有这种要求（需要对实现细节了解）
        头文件中声明
        cpp文件中实现
  走进现代C++
    Item 7: 区分在创建对象时()和{}的区别
    Item 8: 优先使用nullptr而不是0或者NULL
    Item 9: 优先考虑别名声明而不是typedef
      别名声明可以用在模板而typedef不能
      @todo：模板元编程了解
    Item 10: 优先考虑限域枚举而不是全域枚举
      C++98 的enum是全域的
      C++11可以做成scoped enum，也叫枚举类
      都可以指定底层类型
    Item 11: 优先考虑使用delete函数而不是未定义的私有声明
      copy constructor
assignment operator
      delete(public)声明可以在编译器发现错误，而声明为私有并且不定义要在链接时才能发现
      delete可以声明非成员函数
      模板编程中声明哪些参数不能实例化
    Item 12: 使用override声明重载函数
      - The base class function must be virtual.
- The base and derived function names must be identical (except in the case of destructors).
- The parameter types of the base and derived functions must be identical.
- The constness of the base and derived functions must be identical.
- The return types and exception specifications of the base and derived functions must be compatible
- The functions’ reference qualifiers must be identical.
        这里的最后一条是C++11之后才有的，可以限制成员函数使用时对象是左值还是右值引用
```cpp
class Widget {
public:
void doWork() &; // this version of doWork applies only when *this is an lvalue
void doWork() &&; / this version of doWork applies only when *this is an rvalue
};
Widget makeWidget(); // factory function (returns rvalue)
Widget w; // normal object (an lvalue)
w.doWork(); // calls Widget::doWork for lvalues (i.e., Widget::doWork &)
makeWidget().doWork(); // calls Widget::doWork for rvalues (i.e., Widget::doWork &&)
```
      C++11提供了显式声明来表示你想在派生类重写基类函数的意图，如果是的，就加上override的声明
    Item 13: 优先考虑使用const_iterator而不是iterator
    Item 14: 如果函数不抛出异常请使用noexcept
    Item 15: 尽可能使用constexpr
      所有constexpr对象都是const，但是不是多少有const对象都是constexpr
      Constexpr需要保证编译期常量，否则报错
      constexpr函数
        对于C++11来说，实现这种函数有限制，只能有一行？
        C++14没有这种限制
    _Item 16: 使const成员函数线程安全_
    Item 17: 理解特殊成员函数的生成
      C++98
        默认构造函数
        析构函数
        拷贝构造函数
        拷贝赋值函数
        需要的时候会自动生成
public and inline
      C++11 增加了两个
        移动构造函数
        移动赋值函数
      要注意生成规则
        两个拷贝是独立的，声明了一个不会影响另一个生成
        两个移动，只要声明了一个，另一个就不会自动生成了
        - 声明了拷贝操作，移动操作也不会自动生成
- 同样声明了移动操作，拷贝操作也不会自动生成
        生成移动相关操作的条件，都为真
          - No copy operations are declared in the class.
- No move operations are declared in the class.
- No destructor is declared in the class
        多态基类很有用的default关键字
        **Default constructor**: Same rules as C++98. Generated only if the class contains no user-declared constructors
        **Destructor**: Essentially same rules as C++98; sole difference is that destructors are noexcept by default (see Item 14). As in C++98, virtual only if a base class destructor is virtual.
  auto
    Item 5: 优先使用auto而不是显式类型声明
    Item 6: 如果auto不符合预期，使用显式类型初始化方法
  类型推导
    Item 1: 理解模板类型推导
      入参是指针或者引用（不是通用引用）
        忽略引用，然后剩下的部分决定T
      是通用引用
        例子：
```cpp
template<typename T>
void f(T&& param):
```
        Item 24中详细阐释了这里的推导
      不是指针也不是引用
        按值传递
      数组的情况分析
        指针&真正带有size的数组
        将函数声明为constexpr可以在编译期使用
      函数实参
    Item 2: 理解auto类型推导
      依赖模板类型推导
    Item 3: 理解decltype
      C++11中的主要用途
        用于函数模板返回类型，而这个类型依赖形参
      返回变量或者表达式的类型
      C++14支持decltype(auto)
    Item 4: 了解如何获取被推导出的类型