编译时,复制构造函数/复制分配和正常功能调用优化之间是否存在任何区别

Is there any difference between copy constructor/copy assignment and normal function call optimization in compiling?

本文关键字:复制 调用 优化 功能 之间 是否 区别 任何 存在 构造函数 分配      更新时间:2023-10-16

我在测试一个小示例时遇到了一个有趣的编译错误:

#include <iostream>
using namespace std;
class A
{
public:
   A() { cout <<"A created." <<endl; }
   A(A& a) { cout <<"A created by copy constructor." <<endl; }
   ~A() { cout <<"A destoryed." <<endl; }
};
A CreateObject()
{
    A obj;
    return obj;
}   
int main()
{
    A a;
    A b;
    b= CreateObject();
    return 0;
}

这很简单,可能根本没有任何问题。但是,它提示了编译:

copy_constructor.cpp: In function ‘int main()’:
copy_constructor.cpp:23: error: no matching function for call to ‘A::A(A)’
copy_constructor.cpp:9: note: candidates are: A::A(A&)

看来,该程序在编译" B = CreateObject();"时试图调用复制构造函数。但是没有匹配的复制构造函数。这不应该发生,因为它只是一个任务语句,在编译优化时构造函数和正常函数之间是否有任何区别?

A(A& a) { cout <<"A created by copy constructor." <<endl; }
...
b = CreateObject();

根据C 03标准。

是无效的。

在C 03中,b = CreateObject()实际上可以扩展到b = A(CreateObject());。这仅在后来版本的C 中"固定",现在禁止临时副本的创建。

CreateObject()返回一个R HAND值,该值只能由具有A(const A& a)签名的复制构造函数消耗。没有const修饰符,它仅适用于L HAND值。

例如。b = a仍然可以在该签名和扩展中有效,因为您将被允许在构造函数内修改a


这仍然是可复制的设置clang 至C 98标准:http://coliru.stacked-crooked.com/a/50c25c469420ab0f

旧版本的Visual-C 显示出OP。

显示的精确误差

g 也无法正确验证此问题,即使指定C 98。

另请参见https://stackoverflow.com/a/13898867/2879325

您发布的代码编译很好。但是,您应该将复制构造函数从A(A&)更改为A(const A&)