【问题标题】:Correct parameter type for moving object into vector将对象移动到向量中的正确参数类型
【发布时间】:2017-01-21 08:59:37
【问题描述】:

假设我有一个包含一些数据的对象:

struct Object
{
   std::vector<float> data;
}

还有一个包含一些对象的结构:

struct Holder 
{
   private:
   std::vector<Object> objects_;
}

调用代码想要构建一个 Object 并将其添加到 Holder 而不创建副本,因为 Object 可能包含数百万个元素。我最初的想法是让 Holder 来处理这个动作:

struct Holder 
{
   void addObject(Object& object)
   {
      objects_.push_back(std::move(object));
   }
   private:
   std::vector<Object> objects_;
}

但是,其他程序员可能不知道它传递给 Holder::addObject 的对象将使其处于未指定状态并继续对其进行处理。因此,我将其留给调用代码以将对象显式移动到副本中,否则将构造一个副本:

struct Holder 
{
   void addObject(Object object)
   {
      objects_.push_back(std::move(object));
   }
   private:
   std::vector<Object> objects_;
}

调用代码如下:

Holder h;
Object o;
// populate c

h.addObject(std::move(o))

在这种情况下使用 std::move 是否正确?有没有其他更正确和明显的方法来处理这个问题?

【问题讨论】:

  • 使 Object 可移动但不可复制,如果你做错了什么,编译器会告诉你

标签: c++ move stdvector move-semantics


【解决方案1】:

您可以将对象的构造放置到持有人的向量中。这也允许传递一个右值(可以从中移动)。

template<typename... Args>
void emplaceObject (Args... && args) {
  objects_.emplace_back(std::forward<Args>(args)...);
}

std::forward 转发参数的值类别,也就是说如果你用右值调用你的函数,那么std::vector:: emplace_back()也会得到一个右值。

所以h.emplaceObject(std::move(o)) 会调用一次Object 的移动构造函数。

顺便说一句,这叫perfect forwarding.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多