右值绑定和移动的结合
Combination of Rvalue binding and moving
我必须遵循一段代码,我想知道标准是怎么说的。是未定义的行为、已定义但未指定的行为还是明确定义的行为?
using namespace std;
struct Foo {
mutable int obj;
Foo(Foo&&) = default;
Foo(int arg) : obj(arg) {}
void f() const { obj *= 2; }
};
int main()
{
Foo&& a = Foo(5); // Binds temporary, lifetime ends with program
const Foo& b = a; // Binds a, lifetime ends with program
Foo c(std::move(a)); // Moves from a
// a now in defined, but unspecified state
b.f(); // ??
cout << b.obj << endl; // May output 10
return 0;
} // End of lifetime of temporary
注释和我对标准的理解和解释是否正确?
move
从一个值(右值引用构造,而不是调用 std::move
,自然地)在语义上意味着该值应该处于有效(特别是对于销毁有效)但未指定的状态。
但是,C++ 中的 move
并不神奇。这正是您应该做的,而不是语言强迫您做的。
move
使用原始“标量”类型实例与复制它没有什么不同。
move
ing class 类型对从源到目标的每个组件进行成员方式(和父方式)move
。
=default
只是表示“使用我的元素的移动构造函数”,它是一个 int
,而 int
的移动构造函数确实......一个副本(好吧,int
的移动构造函数不存在,但如果存在,它会进行复制)。
move
的语义含义,即您必须使源处于有效(最重要的是可销毁)状态,需要以合理的方式与 std
容器和算法进行交互,并且std
类型的行为方式。
一切都很好,但是标准支持在哪里?
当你 move
使用 =default
a class 时会发生什么,在这种情况下以这个子句结束:
[class.copy]/15.3
otherwise, the base or member is direct-initialized with the corresponding base or member of x
对于直接初始化,告诉您如何从 int&&
直接初始化 int
的子句是:
[dcl.init]/17.8
Otherwise, the initial value of the object being initialized is the (possibly converted) value of the ini-tializer expression.
第二个表达式int a = 7; std::move(a);
的值为7。a
的值没有改变,因为标准不允许。
移动不是魔法。
(引自 n4296,当前标准草案。)
我必须遵循一段代码,我想知道标准是怎么说的。是未定义的行为、已定义但未指定的行为还是明确定义的行为?
using namespace std;
struct Foo {
mutable int obj;
Foo(Foo&&) = default;
Foo(int arg) : obj(arg) {}
void f() const { obj *= 2; }
};
int main()
{
Foo&& a = Foo(5); // Binds temporary, lifetime ends with program
const Foo& b = a; // Binds a, lifetime ends with program
Foo c(std::move(a)); // Moves from a
// a now in defined, but unspecified state
b.f(); // ??
cout << b.obj << endl; // May output 10
return 0;
} // End of lifetime of temporary
注释和我对标准的理解和解释是否正确?
move
从一个值(右值引用构造,而不是调用 std::move
,自然地)在语义上意味着该值应该处于有效(特别是对于销毁有效)但未指定的状态。
但是,C++ 中的 move
并不神奇。这正是您应该做的,而不是语言强迫您做的。
move
使用原始“标量”类型实例与复制它没有什么不同。
move
ing class 类型对从源到目标的每个组件进行成员方式(和父方式)move
。
=default
只是表示“使用我的元素的移动构造函数”,它是一个 int
,而 int
的移动构造函数确实......一个副本(好吧,int
的移动构造函数不存在,但如果存在,它会进行复制)。
move
的语义含义,即您必须使源处于有效(最重要的是可销毁)状态,需要以合理的方式与 std
容器和算法进行交互,并且std
类型的行为方式。
一切都很好,但是标准支持在哪里?
当你 move
使用 =default
a class 时会发生什么,在这种情况下以这个子句结束:
[class.copy]/15.3
otherwise, the base or member is direct-initialized with the corresponding base or member of x
对于直接初始化,告诉您如何从 int&&
直接初始化 int
的子句是:
[dcl.init]/17.8
Otherwise, the initial value of the object being initialized is the (possibly converted) value of the ini-tializer expression.
第二个表达式int a = 7; std::move(a);
的值为7。a
的值没有改变,因为标准不允许。
移动不是魔法。
(引自 n4296,当前标准草案。)