我可以从矢量的开头移动对象吗?为什么不?

时间:2019-11-11 13:18:48

标签: c++ move-semantics

This无法编译。为什么?

#include <iostream>
#include <vector>

struct test_s {
    int a;

    test_s& operator=(test_s &&ts) {
        a = ts.a;
        ts.a = 0;
        return *this;
    }
};

int main ()
{
  std::vector<test_s> v;

  test_s ss = std::move(v.front());

  return 0;
}

错误:

source_file.cpp:20:10: error: call to implicitly-deleted copy constructor of 'test_s'
  test_s ss = std::move(v.front());
         ^    ~~~~~~~~~~~~~~~~~~~~
source_file.cpp:9:13: note: copy constructor is implicitly deleted because 'test_s' has a user-declared move assignment operator
    test_s& operator=(test_s &&ts) {
            ^
1 error generated

是否可以从vector中移动对象(无需调用复制赋值运算符)?

1 个答案:

答案 0 :(得分:5)

  

这不能编译。为什么?

因为您的结构test_s需要一个 move构造函数(或一个 copy构造函数)。

声明:

test_s ss = std::move(v.front());

构造对象ss。尽管您看到=符号,但这不是分配

但是,您已经在结构中定义了移动分配

根据this table,当用户定义 move分配时,编译器不会提供 move构造函数。此外, move 操作应在副本上“回退”,但是(如您在表中所见), copy构造函数被隐式删除(正如编译器建议的那样)

  

是否可以从vector中移动对象(无需调用复制赋值运算符)?

是的,

您应该为您的类定义自己的 move构造函数。 实际上,您应该遵循rule of five

注意: 另请注意,您尝试访问向量中不存在的元素(如某些注释所指出)时,代码具有未定义的行为