【问题标题】:Can std::move move a built-in types or c pointer or arraystd::move 可以移动内置类型或 c 指针或数组吗
【发布时间】:2020-10-19 04:29:28
【问题描述】:

我有 3 个问题:

  1. std::move 可以移动内置类型吗?
int a = 10;
int b = std::move(a);

a 会是无效值吗?


  1. 可以std::move移动指针
int *a = new int[10];
int *b = std::move(a);

a 会变成无效指针还是nullptr


  1. std::move 可以移动一个 c 数组吗?
struct S {
  int array[10];
}
S a;
for(int i=0; i<10; i++)
  a.array[i]=1;
S b;
b = std::move(a);

a.array 会变成无效数组吗?

【问题讨论】:

    标签: c++ c++11 stdmove


    【解决方案1】:

    move 本身除了static_cast 什么都不做。根据cppreference.com

    它完全等同于将静态转换为右值引用类型。

    因此,这取决于您在move 之后分配给的变量的类型,如果该类型具有带右值参数的constructorsassign operators,它可能窃取 em> 原始变量的内容,因此,它可能会将原始变量留在unspecified state中:

    除非另有说明,否则所有被移出的标准库对象都处于有效但未指定的状态。

    回到你的问题,因为对于整数和原始指针等内置文字类型没有特殊的move constructormove assign operator,因此,它只是这些类型的简单副本。因此,对于问题 1 和问题 2,a 仍然有效,并且在 move 之后没有更改。因为C++不允许对C数组直接赋值,所以问题3的代码不能编译。

    --- 编辑---

    您最初的第三个问题是将纯 C 数组分配给另一个,这是该语言所不允许的。

    您更新的第三个问题不同,它在结构中嵌入了一个 C 数组,现在您将一个结构分配给另一个,现在可以编译。因为你的结构没有move assign operator,所以调用了默认的赋值运算符,它进行字节级复制,因此,a 在移动和赋值之后保持不变。

    仅当结构的所有成员都是 POD(普通旧数据)时才会发生这种情况。如果你在你的结构体中添加一个非 POD 成员,赋值语句将无法编译,因为它不能使用默认的“字节级复制”赋值运算符来复制非 POD 成员(例如,字符串对象)。

    struct S {
      std::string something;  // non-POD member
      int array[100];
    };
    S a, b;
    b = std::move(a);  // this line will not compile
    

    【讨论】:

    • 好的,谢谢,我已经编辑了第三个问题,现在数组将成为 struct s 的成员,会发生什么?
    • 您更新的第三个问题中的代码很好,可以编译,并且 a 保持不变。我相应地更新了我的答案。最好添加第 4 个问题而不是替换第 3 个问题,这样读者就不会感到困惑:-)。
    • 顺便说一句,如果它回答了你的问题,你可以接受这个答案,它给其他读者一个明确的信号。
    猜你喜欢
    • 2017-05-28
    • 2016-02-19
    • 1970-01-01
    • 1970-01-01
    • 2020-10-18
    • 2019-06-10
    • 2016-08-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多