我的理解是,当移动基本数据类型时,它将始终执行副本
例如,您永远不能从int
移动,并且未指定原始int
值:
#include <iostream>
int main() {
int x = 100;
int y{std::move(x)};
std::cout << x << " " << y; //always prints "100 100"
}
这是否意味着用户定义类型中的基本数据类型也是如此?
#include <iostream>
#include <vector>
struct Foo{
int i = 100;
std::vector<int> vec={1,2,3,4,5}; //something that probably will have an invariant
};
int main() {
Foo x;
Foo y{std::move(x)};
std::cout << x.i << " " << y.i; //always print "100 100"?
}
标准对于移动后保留这些基本类型值的说法是什么?
答案 0 :(得分:3)
编译器生成的特殊成员函数被指定为基本上对每个类的成员(和基类)执行相应的操作。
因此,struct Foo
i
的行为就像被移动的int
一样。同上vector
。
答案 1 :(得分:0)
这取决于数据成员的移动构造函数。例如,std::vector
的移动构造函数通常会将向量保留为空,但正如您所说,状态未指定。
int的状态不会被改变,因为它们可以简单地移动构造。编译器将使用简单的移动构造类型执行复制。作为@ T.C。在评论中说明,标准要求这种行为。
如果你打算在移动它之后使用你的类,请考虑实现自己的移动构造函数:
struct Foo {
int i = 100;
std::vector<int> vec={1,2,3,4,5};
Foo(Foo&& foo) noexcept : i{std::move(foo.i)}, vec{std::move(foo.vec)} {
foo.vec = {}; // ensure it's empty
foo.i = 0; // ensure it's 0
}
};