2

我有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移动交流阵列吗?
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变成无效数组吗?

4

1 回答 1

3

move它本身什么也不做,而不是 a static_cast。根据cppreference.com

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

因此,它取决于您在 之后分配给的变量的move类型,如果该类型具有constructorsassign operators接受右值参数,它可能会或可能不会窃取原始变量的内容,因此,它可能会将原始变量保留为在一个unspecified state

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

回到你的问题,因为没有特殊的move constructormove assign operator内置的文字类型,如整数和原始指针,所以,它只是这些类型的简单副本。因此,对于问题 1 和问题 2,amove. 因为 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
于 2020-06-29T05:40:36.170 回答