c++ - std::move 可以移动内置类型或 c 指针或数组吗

标签 c++ c++11 stdmove

我有 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 会变成无效数组吗?

最佳答案

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

It is exactly equivalent to a static_cast to an rvalue reference type.

因此,这取决于您在移动之后分配给变量的类型,如果该类型具有构造函数赋值运算符采用右值参数,它可能会也可能不会窃取原始变量的内容,因此,它可能会使原始变量处于未指定状态:

Unless otherwise specified, all standard library objects that have been moved from are placed in a valid but unspecified state.

回到你的问题,因为没有特殊的移动构造函数移动赋值运算符用于内置文字类型,如整数和原始指针,所以,它会只是这些类型的简单拷贝。因此,对于问题 1 和问题 2,a 仍然有效并且在 move 之后没有改变。因为C++不允许对C数组直接赋值,所以问题3的代码编译不通过。

--- 编辑---

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

您更新后的第 3 个问题有所不同,它在一个结构中嵌入了一个 C 数组,现在您正在将一个结构分配给另一个结构,现在可以编译了。因为您的结构没有移动赋值运算符,所以会调用默认赋值运算符,它会进行字节级复制,因此,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

关于c++ - std::move 可以移动内置类型或 c 指针或数组吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62630855/

相关文章:

c++ - 从 Java : How to define lambda members for enum types in C++? 翻译

c++ - 多态记录器(虚拟模板函数?)

c++ - 一般来说,处理虚假唤醒的正确方法是什么?

c++ - 在没有赋值的情况下调用 std::move() 时会发生什么

c++ - std::vector、std::move 和指针失效

c++ - 如何从 C++ 中的枚举类打印出字符串?

c++ - 指向 POD 结构的 C/C++ 指针也指向第一个结构成员

c++ - nothrow 在 C++11 中构造虚类

c++ - SFINAE 将实例化类型限制为 std::chrono::duration 类型

c++ - std::move 和 std::forward 之间的混淆