提问人:Gergely Tomcsányi 提问时间:8/12/2017 最后编辑:gsamarasGergely Tomcsányi 更新时间:8/12/2017 访问量:244
为什么在将 rvalue by value 传递给函数时不调用 copy-constructor
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() */
为什么当我按值传递给 时没有调用复制构造函数?这是否意味着在 C++98 中按值或引用传递右值没有区别?是优化吗?和 是 和 完全相同的对象吗?A(2)
testFunction1()
A(2)
arg
testFunction1()
答:
3赞
gsamaras
8/12/2017
#1
是优化吗?
是的!它被称为复制省略,如果可能的话,可以省略(绕过)副本,具体取决于编译器。
因此,在你的例子中,编译器明白它可以在不调用复制构造函数的情况下逃脱,并且正是这样做的。请注意,即使您使用了 ,例如调用 的打印成员函数 ,编译器仍可出于优化目的使用复制省略。换句话说,不使用不是导致此行为的原因。arg
A
arg
如果您使用古老的编译器,或者调整当前编译器的设置,您可能会首先看到预期的结果。
使用 c++17,在这种情况下可以保证复制省略,正如 Guillaume Racicot 所提到的。
评论
1赞
Guillaume Racicot
8/12/2017
我什至提到,在 C++17 中,他的情况肯定会有复制省略
评论