C++ 在移动构造期间,可以对从对象移动的基本类型成员的值说些什么?

C++ 在移动构造期间,可以对从对象移动的基本类型成员的值说些什么?,c++,c++11,language-lawyer,move-semantics,C++,C++11,Language Lawyer,Move Semantics,考虑一下这个代码 Foo f1; Foo f2{ std::move(f1) }; 我希望f1的成员值不再一定包含默认构造函数给定的值。但是,使用Foo的这种实现对多个编译器进行测试表明情况并非如此 class Foo { public: Foo() = default; Foo(Foo &&) = default; std::string s{ "foo" }; bool t{ true }; bool f{ false }; };

考虑一下这个代码

Foo f1;
Foo f2{ std::move(f1) };

我希望
f1
的成员值不再一定包含默认构造函数给定的值。但是,使用
Foo
的这种实现对多个编译器进行测试表明情况并非如此

class Foo
{
public:
    Foo() = default;
    Foo(Foo &&) = default;

    std::string s{ "foo" };
    bool t{ true };
    bool f{ false };
};
移动后
f1.t
始终为
true
f1.f
始终为
false
。如中所述,我希望值不是不确定的,就是两个布尔值具有相同的值。但是,它们似乎获得了与从默认构造函数获得的值相同的值

这只是我的编译器的一个实现细节(巧合的是相同的)还是这在标准中

移动后
f1.t
始终为
true
f1.f
始终为
false

对于基本类型,移动就是复制。您不希望您的实现复制bool将旧的值归零-这是不必要的额外工作。在一个简单的POD中,移动将只是一个
memcpy
——但是如果你的建议会发生,那么你还必须执行
memset
。什么都不做要快得多

这只是我的编译器的一个实现细节(巧合的是相同的),还是在标准中

这在以下标准中:

非联合类X的隐式定义的复制/移动赋值运算符执行成员复制- /移动其子对象的指定。[…]每个子对象都按以下方式指定 适合其类型:
-[…]
-如果子对象是标量类型,则使用内置赋值运算符


“我希望f1的成员值现在可以取消初始化”您不能取消已初始化的内容。您可以将未初始化的内容移动到其位置:不,这将是未定义的行为(从未初始化的变量读取)。但您的示例没有显示这一点。是的,可能我对此不确定。您的意思是:1)最后一行是未定义的行为,因为
initialized
未初始化。或者2)最后一行没有问题,因为
已初始化
实际上已初始化?如果2)何时初始化为“”?否,仅初始化一次。移动构造函数利用了
std::string
的移动构造函数,它将状态从
initialized.state
中移除。这恰好是一个相当于“”的字符串`