我可以将 std::move 与不提供 move 构造函数的类一起使用吗?
can I use std::move with class that doesn't provide a move constructor?
我有这样的类:
class myClass
{
int x[1000];
public:
int &getx(int i)
{
return x[i];
}
}
请注意,我在这里没有提供移动结构。
如果我使用以下代码:
myClass A;
auto B=std::move(a);
A是移动到 B 还是因为我没有提供移动构造函数,A 被复制到 B?
对象是否有任何默认的移动构造函数?如果是,它如何与指针和动态分配的数组一起工作?
虽然您没有提供显式移动构造函数,但编译器为您提供了隐式移动构造函数。
如果类 X 的定义没有显式声明移动构造函数,则当且仅当
- X 没有用户声明的复制构造函数,并且
- X 没有用户声明的复制赋值运算符,
- X 没有用户声明的移动分配运算符,
- X 没有用户声明的析构函数,并且
- 移动构造函数不会隐式定义为已删除。
所以你的问题的答案是:不,A 没有复制到 B。
不清楚您在其他问题中问了什么。请具体说明更多详细信息。
对象是否有任何默认的移动构造函数?
是的,在您的情况下。对于任何类型T
,移动构造函数只有在满足某些条件时才隐式声明。更多细节可以在 cpperference.com 看到。
如果是,它如何与指针和动态分配的数组一起工作?
默认实现将创建指针的浅拷贝。因此,多个对象将指向动态分配的数组。这将导致问题。有关该主题的更多信息,请参阅三人法则。
如果您有指向动态分配数组的指针,则需要:
- 提供一个显式定义的复制构造函数,该构造函数对动态分配的数组执行正确的操作。这样做的副作用是默认的移动构造函数将被隐式删除。和/或
- 提供一个显式定义的移动构造函数,您可以在其中适当地移动动态分配数组的所有权。
移动构造函数是为类生成的,因为您没有定义任何避免生成它的方法(作为用户定义的析构函数或复制构造函数(
自动生成的移动构造函数将移动每个成员。对于int[1000]
它等同于复制。
如果没有为类类型(结构、类或联合(提供用户定义的移动构造函数,并且满足以下所有条件:
- 没有用户声明的复制构造函数。
- 没有用户声明的复制分配运算符。
- 没有用户声明的移动分配运算符。
- 没有用户声明的析构函数
然后编译器将移动构造函数声明为其类的非显式内联公共成员,签名为 T::T(T&&(。
引用自 cpp首选项
基本上,是的,只要您不定义复制构造函数、复制赋值重载、移动赋值重载或析构函数,就会创建默认移动构造函数。否则,您必须自己定义行为或使用:
class_name ( class_name && ) = default;
这将显式声明移动构造函数的默认版本。
你的问题与此类似。请注意,std::move 只是一个强制转换。您的值a将被强制转换为右值引用,但在您的情况下,原始对象不会被掠夺或窃取。
要正确使用 API 或习语,您必须将其用于正确的事情。例如.class对于在堆上分配了大量对象数据的对象,移动最有意义。这样的物体很容易被偷走,"移动"可以使被偷的物体处于明确定义的状态。例如,规范示例可以是堆上带有字符串数据的某种类型的字符串类。
就您而言,您希望发生什么?假设 a是某个函数中的本地变量,即假设a在堆栈上。假设b是全局或文件范围或匿名命名空间变量,即不在堆栈上。从a移动到b时您希望发生什么?
对于一根绳子,偷窃是有意义的。就您而言,盗窃是荒谬的。
- 如何将enable-if与模板参数和参数包一起使用
- 如何将PERF_AMPLE_READ与mmap一起使用
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 瓦尔格林德:数学函数"Conditional jump or move depends on uninitialised value(s)"
- Usages of std::move
- 在C++中对T*类型执行std::move的意外行为
- 如何将C++中的库和头与MinGW一起使用
- 关于std::move的使用,是否有编译警告
- 我应该实现右值推送功能吗?我应该使用std::move吗
- 将--whole archive链接器选项与CMake和具有其他库依赖项的库一起使用
- 为什么我不能将 rand() 与数组的大小一起使用?
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 不能将复制初始化与隐式转换的多个步骤一起使用
- 通过实例理解std::move及其目的
- 将fold表达式与std::一起用于两个元组
- spdlog标头仅与外部fmt一起使用.spdlog错误:'内部':不是'fmt'
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 我可以将 std::move 与不提供 move 构造函数的类一起使用吗?
- 当move语义与std::move一起工作时
- 为什么RVO不能与move构造函数一起工作