我有以下代码:
#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&)复制构造函数时,程序不会编译。
您所看到的是复制省略和正在制作的实际副本的混合。由于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 的保证复制省略
| 归档时间: |
|
| 查看次数: |
81 次 |
| 最近记录: |