默认移动构造函数和引用成员 [英] Default move constructor and reference members

查看:142
本文介绍了默认移动构造函数和引用成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从N3337的[12.8] [11]:

From [12.8] [11] of N3337:


非联合类X的隐式定义的复制/移动构造函数执行其基地和成员的成员复制/移动。 [注意:忽略非静态数据成员的括号或初始值。另请参见12.6.2中的示例。 -end note]初始化的顺序与用户定义构造函数中的基址和成员的初始化顺序相同(见12.6.2)。让 x 是构造函数的参数,或者对于move构造函数,引用参数的xvalue。每个基础或非静态数据成员都以适合其类型的方式进行复制/移动:

The implicitly-defined copy/move constructor for a non-union class X performs a memberwise copy/move of its bases and members. [ Note: brace-or-equal-initializers of non-static data members are ignored. See also the example in 12.6.2. —end note ] The order of initialization is the same as the order of initialization of bases and members in a user-defined constructor (see 12.6.2). Let x be either the parameter of the constructor or, for the move constructor, an xvalue referring to the parameter. Each base or non-static data member is copied/moved in the manner appropriate to its type:

- 如果成员是数组,则每个元素都直接初始化为对应的子对象x;

— if the member is an array, each element is direct-initialized with the corresponding subobject of x;

- 如果成员m具有右值引用类型T&&,则它被直接初始化为 static_cast< T& ;&>(xm);

— if a member m has rvalue reference type T&&, it is direct-initialized with static_cast<T&&>(x.m);

- 否则,基数或成员直接初始化为x 。

— otherwise, the base or member is direct-initialized with the corresponding base or member of x.

这更多的是一个澄清,但是我看不到在该子句中提及的左值引用成员。因为它没有提到它们,默认情况下它似乎是说它们是隐性成员移动的一部分,但下面的不会工作;

This is really more of a clarification, but I can't see any mention of lvalue reference members in that clause. Since it doesn't mention them, by default it seems to say that they are part of the implicit memberwise move, yet the following would not work;

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}'

因此,可以安全地假设默认移动构造函数区分成员是引用,而只是执行

So is it safe to assume that the default move constructor distinguishes that a member is a reference and would simply just do

int& z = y;

不调用 std :: move

推荐答案

它由类成员访问表达式的规范来处理。关键部分是

It's handled by the specification of class member access expressions. The key part is


x 是构造函数的参数,

Let x be either the parameter of the constructor or, for the move constructor, an xvalue referring to the parameter.

换句话说,

struct X { int x, &y; };

相当于

X::X(X&& other) : x(std::move(other).x), y(std::move(other).y) {}

这里重要的是类成员访问表达式的结果 xm ,其中 m 命名非静态数据成员,如果 m 有引用类型,但是xvalue如果 x 是右值, m 有非引用类型。 (参见[expr.ref] / 4。)这确保了左值引用成员将用左值初始化。

The important thing here is that the result of a class member access expression x.m, where m names a non-static data member, is always an lvalue if m has reference type, but an xvalue if x is an rvalue and m has non-reference type. (See [expr.ref]/4.) This ensures that lvalue reference members will be initialized with lvalues.

这篇关于默认移动构造函数和引用成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆