来自N3337的[12.8][11]:
非联合类X的隐式定义的复制/移动构造函数对其基类和成员执行逐成员的复制/移动。[注:忽略非静态数据成员的花括号或等号初始化项。参见12.6.2中的示例。——注释结束] 初始化顺序与用户定义构造函数中基类和成员的初始化顺序相同(见12.6.2)。设x为构造函数的参数,或对于移动构造函数,是引用该参数的xvalue。每个基类或非静态数据成员以适合其类型的方式进行复制/移动:
— 如果成员是数组,则每个元素均使用x的相应子对象进行直接初始化;
— 如果成员m具有rvalue引用类型T&&,则使用
static_cast<T&&>(x.m)
进行直接初始化;— 否则,基类或成员将使用x的相应基类或成员进行直接初始化。
这实际上更像是一个澄清,但我在那个条款中没有看到任何关于左值引用成员的提及。由于它没有提到它们,因此默认情况下似乎它认为它们是隐式的逐成员移动的一部分,然而下面的例子不起作用:
int x = 5;
int& y = x;
int& z(std::move(y)); //error: invalid initialization of non-const reference of type 'int&' from an rvalue of type 'std::remove_reference<int&>::type {aka int}'
那么可以安全地假设默认的移动构造函数会区分成员是一个引用,并且只会执行
int& z = y;
没有调用 std::move
?
int &z(std::move(y));
不是合法的。int &z = y;
是合法的,它使得z
成为当前命名为x
和y
的int
对象的第三个名称。我不确定你的问题是什么? - M.Mm
,它的初始化就像是通过语句T m(other.m);
进行的一样。 - M.M