从N3337的[12.8] [11]中:
非联合类X的隐式定义的复制/移动构造函数执行其基和成员的成员式复制/移动。[注意:非静态数据成员的大括号或相等初始化器将被忽略。另请参见12.6.2中的示例。— —注释[end note]初始化的顺序与用户定义的构造函数中基和成员的初始化的顺序相同(请参见12.6.2)。让我们
x
将其作为构造函数的参数,或者将其作为移动构造函数的xvalue引用该参数。每个基本或非静态数据成员都按照适合其类型的方式进行复制/移动:—如果成员是数组,则用x的相应子对象直接初始化每个元素;
—如果成员m具有右值引用类型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}'
因此可以安全地假设默认的move构造函数可以区分成员是引用,而仅仅是
int& z = y;
没有电话std::move
?
它由类成员访问表达式的规范处理。关键部分是
让我们
x
将其作为构造函数的参数,或者将其作为移动构造函数的xvalue引用该参数。
换句话说,默认的move构造函数
struct X { int x, &y; };
相当于
X::X(X&& other) : x(std::move(other).x), y(std::move(other).y) {}
这里重要的是,类成员访问表达式的结果(x.m
其中m
命名为非静态数据成员)在m
具有引用类型的情况下始终为左值,而在x
具有右m
引用且具有非引用类型的情况下为xvalue 。(请参阅[expr.ref] / 4。)这确保将使用左值初始化左值引用成员。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句