代码之家  ›  专栏  ›  技术社区  ›  Bruno Grieder

我应该依赖复制省略还是移动语义?

  •  1
  • Bruno Grieder  · 技术社区  · 7 年前

    给定向量

    std::vector<BigObject> v;
    

    和工厂功能

    BigObject genBigObject();
    

    我想避免抄袭 BigObject 实例。

    哪一个更快?

    v.push_back(genBigObject());
    

    v.push_back(std::move(genBigObject()));
    

    我能相信复制省略会 大目标 ,但是,嗯……)

    2 回复  |  直到 7 年前
        1
  •  10
  •   Barry    7 年前

    目的 std::move() 就是拿一个 左值 并将其视为 右值 为了让其他函数明白,如果它们愿意的话,它们可以分解对象的内部。

    genBigObject() 已是右值。你不需要 move() 这是我的梦想- 移动() 根本无法为你提供任何有价值的东西。所以不要这样做。你甚至不需要考虑下游到底发生了什么- 移动() 是代码和读者的一个信号,表明您正在做一些可能不安全的事情,但在本例中。。。你不是。

    为此 具体的 case,您正在调用 push_back() 推回 或者稍早一点打电话给 移动() 没什么区别。

        2
  •  2
  •   Yakk - Adam Nevraumont    7 年前

    push_back 不支持省略;它采用右值引用或常量左值引用。

    你有一个实际的右值;使命感 std::move int x = 7; static_cast<int&>(x); --几乎是一个中午,有时是一种悲观。

    解决您的核心问题,即您希望省略,我们可以做些事情。

    你可以省去建筑的麻烦 BigObject

    template<class F>
    struct emplacer {
      F f;
      operator std::result_of_t<F&&()>()&&{ return std::forward<F>(f)(); }
      operator std::result_of_t<F&()>()&{ return f(); }
    };
    template<class T>
    emplacer(T&&)->emplacer<T&&>;
    

    现在您可以执行以下操作:

    v.emplace_back( emplacer{ &getBigObject });
    

    大目标 将直接放置到向量缓冲区中(禁止过度贪婪 大目标 构造器)。

    Live example