在这个问题中,我们已经知道RVO不能应用于像这样的表达式p.first.
在评论中,还建议RVO通常不适用于像r声明之类的表达式auto& r = p.first.标准是否要求这种行为尚不清楚.
在具有类返回类型的函数的return语句中,当表达式是非易失性自动对象的名称时(除了函数参数或由处理程序的异常声明引入的变量([except.handle]) ))具有与函数返回类型相同的类型(忽略cv-qualification),通过将自动对象直接构造到函数的返回值中,可以省略复制/移动操作
在下面的代码中,对象r的名称是否也称为o,当RVO在return语句中形成表达式时允许使用RVO ?
int o = 42;
int& r = o;
Run Code Online (Sandbox Code Playgroud) 从N3337的[12.8] [11]:
非联合类X的隐式定义的复制/移动构造函数执行其基础和成员的成员复制/移动.[注意:忽略非静态数据成员的大括号或大小写.另请参见12.6.2中的示例.-end note]初始化顺序与用户定义构造函数中基数和成员的初始化顺序相同(见12.6.2).让我们
x为构造函数的任何参数,或者对于移动构造函数,x值指的是参数.以适合其类型的方式复制/移动每个基本或非静态数据成员:- 如果成员是一个数组,则使用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}'
Run Code Online (Sandbox Code Playgroud)
因此,可以安全地假设默认的移动构造函数区分成员是一个引用而且只是这样做
int& z = y;
Run Code Online (Sandbox Code Playgroud)
没有电话std::move?