2

假设有一个A带有移动构造函数的类。考虑一下:

A get()
{
    A a;
    return std::move( a );
}

// later in the code
A aa = get();

这里显式调用std:move强制调用移动构造函数,A因此它可能会抑制调用时的返回值优化get()。因此,据说更好的实现get()是这样的:

A get()
{
    A a;
    return a;
}

但是返回值优化不是 C++11 标准的一部分,所以如果编译器由于某种原因决定在调用get(). 在这种情况下,A将在返回时调用的复制构造函数get()对吗?

那么第一个实现不是get()更可取吗?

4

1 回答 1

3

编译器应该使用移动构造函数,但我没有看到标准中的义务:在关于临时对象的部分中总是说“复制/移动构造函数”

标准 ISO/IEC 14882:2011 C++:

"

12.1/9

复制构造函数 (12.8) 用于复制类类型的对象。移动构造函数 (12.8) 用于移动类类型对象的内容。

12.8/32

当满足或将满足复制操作的省略条件时,除了源对象是函数参数,并且要复制的对象由左值指定之外,选择复制构造函数的重载决策是首先执行好像对象是由rvalue指定的。如果重载决议失败,或者如果所选构造函数的第一个参数的类型不是对对象类型的右值引用(可能是 cv 限定的),则再次执行重载决议,将对象视为 左值. [注意:无论是否会发生复制省略,都必须执行此两阶段重载解析。它确定如果不执行省略则要调用的构造函数,并且即使调用被省略,所选构造函数也必须是可访问的。——尾注]

"

左值=T &
右值=T &&

因此,它说首先,编译器会查找是否找到移动构造函数,然后会查找移动构造函数。

因此,如果您的编译器符合标准,它将调用移动构造函数。

我只附加了有趣的内容:

"
12.8/31 当满足某些条件时,允许实现省略类对象的复制/移动构造,即使对象的复制/移动构造函数和/或析构函数有副作用。
"

...因此,即使这些构造函数/析构函数存在副作用,也可以跳过它们

于 2013-08-14T11:14:37.687 回答