C ++ 11 Standard中的哪个子句在下面的函数foo()的返回中支持移动构造函数调用?

时间:2013-06-25 11:47:17

标签: c++ c++11 standards move

C ++ 11 Standard中的哪个子句支持在下面的函数foo()返回时调用move构造函数?

#include <iostream>

class A
{
    public:
    A() { std::cout << "Ctor\n"; }
    A(const A&) {std::cout << "Copy ctor\n";}
    A(A&&) {std::cout << "Move ctor\n";}
};

A foo(A&& ra) { return std::move(ra); }

int main()
{
    A a = foo(A());
}

这个问题已被关闭我相信昨天,现在它被“搁置”了,结束的原因是它过于本地化了。我很难理解SO中关于C ++ 11标准的特定问题的帖子如何被认为是“过于本地化”。对我而言,这是一个矛盾,因为标准是“事实上”每个C ++程序员应该寻找的最终文档,如果对语言有疑问的话。

1 个答案:

答案 0 :(得分:3)

关于代码有很多条款。特别是初始化(第8节的后面),重载解析(第13节)以及更基本的第3和第5条,以理解表达式和引用类型的值类别。

首先,表达式A()是由默认构造临时结果产生的类prvalue。

它通过直接引用绑定初始化右值引用ra

ra通过直接引用绑定初始化move的参数,move返回类型为A的xvalue,再次通过直接引用绑定初始化,初始化返回值foo,通过重载解析到移动构造函数,将第一个临时值移动到foo的返回值,也是临时值。

表达式foo(A())是引用第二个临时表的类prvalue。

这通常会通过重载初始化a来解析移动构造函数的prvalue,并从a的返回值移动构造foo - 但是由于12.8 / 32p3 :

  

当一个未绑定到引用(12.2)的临时类对象被复制/移动到具有相同cv-nonqualified类型的类对象时,可以通过直接构造临时对象来省略复制/移动操作进入省略的复制/移动目标

因此,foo的返回值通常直接在a的存储中构造,并且省略了第二次移动构造。