C++右值引用之move使用场景和 emplace 系列函数

 

先说结论, 并不是..

Scott Meyers

ec = effective c++

mec = more effective c++

es = effective stl

emc = effective modern c++

FAQ

  1. 返回值情形下需要为返回的参数或局部变量执行std::move(arg) 吗?

    不需要, 因为存在(N)RVO, 即(具名)返回值优化, 需要注意的是 return 语句后面不要使用?: 之类的三目运算符, 这样编译器不会执行优化, 而是进行拷贝(不调用 move-ctor)

    最佳实践就是直接写: return val;

  2. 什么时候需要写std::move() ?

    需要将左值转为将亡值供 move-ctor 或者 move-assignment-operator 使用时, 此时该左值不应该有其他对象调用, 执行转换之后应该将左值转为 nullptr 等类型.

    如果使用了emplace_back 之类的函数, 则不需要使用std::move()

  3. 什么时候都是 emplace 系列函数优于 push 系列函数吗? emc42

    如果下面三个条件都满足, 那么才应该使用 emplace 系列函数. (置入优于插入)

    • 值是通过构造函数添加到容器,而不是直接赋值 (没有临时对象的创建和销毁)

    • 传递的实参类型与容器的初始化类型不同 (例如, 通过字符串字面量(const char*) 传入 vector 时候)

    • 容器不拒绝重复项作为新值, 例如: 关联式容器需要执行插入值存在性判断(例如哈希集合), 此时不应使用 emplace, 理由如下

      置入实现通常会创建一个具有新值的节点,以便可以将该节点的值与现有容器中节点的值进行比较。如果要添加的值不在容器中,则链接该节点。但是,如果值已经存在,置入操作取消,创建的节点被销毁,意味着徒增了构造和析构时的开销。