2

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

#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++ 程序员应该寻找的最终文档,以防对语言有疑问。

4

1 回答 1

3

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

首先,表达式A()是一个类纯右值,由临时构造的默认构造产生。

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

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

该表达式foo(A())是一个引用第二个临时值的类纯右值。

然后,这通常会通过重载解析纯右值到移动构造函数来复制初始化,并从- 但是由于 12.8/32p3的返回值a移动构造:afoo

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

因此 的返回值foo通常直接在 的存储中构造它a,而这个第二步构造被省略了。

于 2013-06-25T12:21:39.247 回答