临时对象的复制构造函数调用

mic*_*t38 4 c++

我有以下代码:

#include <iostream>
using namespace std;
struct A
{
    A() {}
    A(const A&)  { cout << "copy const" << endl; }
    A(A&)  { cout << "copy non const" << endl; }
};
A f(A a)
{
    return a;
}
int main() {
  A a1 = f(A());
}
Run Code Online (Sandbox Code Playgroud)

A(A&)拷贝构造函数被调用。为什么A(const A&)不调用,因为我传递了一个临时对象?当我注释掉A(const A&)复制构造函数时,程序不会编译。

Nat*_*ica 8

您所看到的是复制省略和正在制作的实际副本的混合。由于f需要a通过值,它需要复制A()a。编译器认为这个副本确实不需要,所以它忽略了它,而是直接构造,a所以你看不到任何调用。在fwhen you的正文中return a;,它需要复制a到返回值中。由于a是左值,因此A(A&)A(const A&)您看到对非 const 复制构造函数的调用更好的匹配。然后a1需要从f的返回值进行初始化。再次复制省略再次发挥作用,而不是看到副本,它只是直接将返回值放入a1的存储中。

所以,elide,非常量复制,elide,它只留下输出 copy non const


删除时会出现错误,A(const A&)因为即使删除了这些副本,C++ 仍然需要在 C++17 之前有复制构造函数。


如果您使用 gcc 或 clang 进行编译并使用,-fno-elide-constructors您实际上可以看到这些副本。您可以在此实时示例中看到这一点。请注意,我曾经-std=c++11关闭 C++17 的保证复制省略