测试一个小示例时,我遇到了一个有趣的编译错误:
#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
修饰符,则仅适用于左手值。
例如b = a
,对于该签名和扩展,仍然是有效的,因为将允许您a
在构造函数内部进行修改。
这仍然是可复制的,将clang ++设置为C ++ 98标准:http : //coliru.stacked-crooked.com/a/50c25c469420ab0f
较旧的Visual-C ++版本显示出OP所显示的精确错误。
即使明确指定了C ++ 98,g ++也无法正确验证这一点。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句