隐式移动方法总是保留基础数据吗?

时间:2016-09-26 13:47:15

标签: c++ c++11 copy move move-semantics

我的理解是,当移动基本数据类型时,它将始终执行副本 例如,您永远不能从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"?

}

标准对于移动后保留这些基本类型值的说法是什么?

2 个答案:

答案 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
    }
};