什么是复制省略以及它如何优化复制和交换习语?

我正在阅读复制和交换.

我尝试阅读 Copy Elision 上的一些链接,但无法正确理解它的含义.有人可以解释一下这个优化是什么,特别是下面的文字是什么意思

I tried reading some links on Copy Elision but could not figure out properly what it meant. Can somebody please explain what this optimization is, and especially what is mean by the following text

这不仅仅是一个方便的问题,而且实际上是一种优化.如果参数 (s) 绑定到左值(另一个非常量对象),则在创建参数 (s) 时会自动制作该对象的副本.但是,当 s 绑定到右值(临时对象,文字)时,通常会省略副本,从而节省对复制构造函数和析构函数的调用.在参数被接受为常量引用的赋值运算符的早期版本中,当引用绑定到右值时不会发生复制省略.这会导致创建和销毁一个额外的对象.

This is not just a matter of convenience but in fact an optimization. If the parameter (s) binds to a lvalue (another non-const object), a copy of the object is made automatically while creating the parameter (s). However, when s binds to a rvalue (temporary object, literal), the copy is typically elided, which saves a call to a copy constructor and a destructor. In the earlier version of the assignment operator where the parameter is accepted as const reference, copy elision does not happen when the reference binds to a rvalue. This results into an additional object being created and destroyed.

推荐答案

复制构造函数的存在是为了进行复制.理论上,当你写一行时:

The copy constructor exists to make copies. In theory when you write a line like:

CLASS c(foo());

编译器必须调用复制构造函数将foo()的返回值复制到c中.

The compiler would have to call the copy constructor to copy the return of foo() into c.

复制省略是一种跳过调用复制构造函数以避免支付开销的技术.

Copy elision is a technique to skip calling the copy constructor so as not to pay for the overhead.

比如编译器可以安排foo()直接将其返回值构造成c.

For example, the compiler can arrange that foo() will directly construct its return value into c.

这是另一个例子.假设您有一个函数:

Here's another example. Let's say you have a function:

void doit(CLASS c);

如果你用实参调用它,编译器必须调用复制构造函数,这样原始参数就不能被修改:

If you call it with an actual argument, the compiler has to invoke the copy constructor so that the original parameter cannot be modified:

CLASS c1;
doit(c1);

但现在考虑一个不同的例子,假设你这样调用你的函数:

But now consider a different example, let's say you call your function like this:

doit(c1 + c1);

operator+ 将不得不创建一个临时对象(一个右值).与在调用 doit() 之前调用复制构造函数不同,编译器可以传递由 operator+ 创建的临时对象并将其传递给 doit()> 代替.

operator+ is going to have to create a temporary object (an rvalue). Instead of invoking the copy constructor before calling doit(), the compiler can pass the temporary that was created by operator+ and pass that to doit() instead.

相关文章