【问题标题】:Move Semantics for std::vector member移动 std::vector 成员的语义
【发布时间】:2013-10-14 09:58:13
【问题描述】:

我想确保我正确理解这一点。我在这里问它,因为我没有明确说明它的资金。

例如我有一个三角形网格类,基本上是这样构建的:

class Mesh
{
public:
    struct Face 
    {
        unsigned int a;
        unsigned int b;
        unsigned int c;
    };
//... 
private:
    std::string            file;
    std::vector<glm::vec3> vertices;
    std::vector<glm::vec3> normals;
    std::vector<glm::vec2> texcoord;
    std::vector<Face>      faces;   
}

由于网格中的数据可能会变得非常大,我想实现正确的移动语义。对于指针类型,我完全理解这一点,但要触发右值构造函数,我需要使用移动,对吗?

例如,右值构造函数将是:

Mesh::Mesh(Mesh&& other)
: file(std::move(other.file)),
  vertices(std::move(other.vertices)),
  normals(std::move(other.normals)),
  texcoord(std::move(other.texcoord)),
  faces(std::move(other.faces) {}

注意:在有人指出明显之前,该应用程序在许多地方都使用了 share_ptr。但是我不想人为地限制类的使用。

【问题讨论】:

  • 我认为您理解正确,您的代码对我来说看起来不错。 (除了缺少右括号,但我认为这是一个复制/粘贴错误,对吧?)
  • 请注意,编译器生成的或默认的移动构造函数会为您执行此操作。
  • glm::vec3, glm::vec2 是什么?如果它们是类,那么它们也应该实现移动语义。
  • @Jagannath 这并不重要,因为vector 本身被移动了,这意味着元素根本不会被复制或移动。
  • @Jagannath 为什么?移动整个std::vector 只会转移内部缓冲区所有权。当然,当向量被调整大小时,他们会从中受益,但对于Mesh 自己的移动 ctor 而言,这不是必需的。

标签: c++ c++11 c++-standard-library move-constructor


【解决方案1】:

是的,你必须像你一样在移动构造函数中使用std::move()。但是,您的移动构造函数完全复制了默认构造函数。如果您的班级没有定义以下任何一项:

  • 复制构造函数
  • 复制赋值运算符
  • 移动赋值运算符
  • 析构函数

然后将为您生成一个默认的移动构造函数,完全按照您所做的那样做。您最好不要定义定义并依赖默认定义。

即使你的类定义了上面的一些,你也可以要求编译器生成默认的移动构造函数:

class Mesh
{
public:
  Mesh(Mesh &&) = default;
  // the rest as before
};

这样,您不必定义它,即使您稍后添加其他成员,它也可以工作(没有忘记将它们添加到手动移动构造函数的风险)。


不幸的是,以上都不适用于 Visual Studio 2015 或更早版本,它无法生成默认移动构造函数并且不支持 = default 进行移动操作。因此,如果您的目标是 VS

【讨论】:

  • 我非常感谢这里的明确答案,以及有关使用带有 default 关键字的默认版本的信息。谢谢!
猜你喜欢
  • 2012-01-05
  • 2011-11-25
  • 2021-12-12
  • 2013-10-17
  • 2015-09-19
  • 1970-01-01
  • 2013-10-15
  • 1970-01-01
  • 2018-02-02
相关资源
最近更新 更多