[英]Why is the copy-constructor not called when returning by-value a list-initialized object?
[英]Why isn't the copy-constructor called when passing rvalue by value to function
我以某种方式错过了这件事,但我感到惊讶。 考虑以下代码示例:
#include <iostream>
class A
{
int a;
public:
A(int a) : a(a) { std::cout << "Normal constructor called." << std::endl; }
A(const A& orig) : a(orig.a) { std::cout << "Copy constructor called." << std::endl; }
};
void testFunction1(const A arg) { std::cout << "testFunction1()" << std::endl; }
void testFunction2(const A& arg) { std::cout << "testFunction2()" << std::endl; }
int main()
{
testFunction1(A(2));
testFunction2(A(2));
return 0;
}
我期望得到以下结果:
/* Normal constructor called. */
/* Copy constructor called. */
/* testFunction1() */
/* Normal constructor called. */
/* testFunction2() */
但是我错了。 确切的结果如下:
/* Normal constructor called. */
/* testFunction1() */
/* Normal constructor called. */
/* testFunction2() */
当我按值将A(2)
传递给testFunction1()
时,为什么不调用复制构造函数? 这是否意味着在C ++ 98中按值或引用传递右值之间没有区别? 是优化吗? A(2)
和arg
在testFunction1()
是否完全是同一对象?
是优化吗?
是! 这称为Copy Elision ,如果可能的话,可以根据编译器删除(绕过)副本。
因此,在您的情况下,编译器知道无需调用复制构造函数即可摆脱该错误,并做到了这一点。 请注意,即使您使用arg
,例如调用A
的打印成员函数,出于优化目的,编译器仍然可以使用复制省略。 换句话说,不使用arg
并不是此行为的原因。
如果您使用古老的编译器,或者调整当前编译器的设置,则可能会在一开始就看到期望的结果。
如Guillaume Racicot所述,使用c ++ 17可以确保在这种情况下进行复制省略。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.