带赋值运算符的右值引用
在本文中 http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/comment-page-1/#comment-1877:
T& T::operator=(T const& x) // x is a reference to the source
{
T tmp(x); // copy construction of tmp does the hard work
swap(*this, tmp); // trade our resources for tmp's
return *this; // our (old) resources get destroyed with tmp
}
但是在从复制省略的角度来看,这个公式显然效率低下!现在“显而易见”的是,编写复制和交换赋值的正确方法是:
T& operator=(T x) // x is a copy of the source; hard work already done
{
swap(*this, x); // trade our resources for x's
return *this; // our (old) resources get destroyed with x
}
出于复制省略的考虑,我们应该使用按值而不是 const 引用的参数来编写赋值运算符。
使用右值引用功能,像下面这样编写赋值运算符是否更好? :
T& operator=(T&& x)
{
swap(*this, x);
return *this;
}
终于没有区别了?
In this article http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/comment-page-1/#comment-1877 :
T& T::operator=(T const& x) // x is a reference to the source
{
T tmp(x); // copy construction of tmp does the hard work
swap(*this, tmp); // trade our resources for tmp's
return *this; // our (old) resources get destroyed with tmp
}
but in light of copy elision, that formulation is glaringly inefficient! It’s now “obvious” that the correct way to write a copy-and-swap assignment is:
T& operator=(T x) // x is a copy of the source; hard work already done
{
swap(*this, x); // trade our resources for x's
return *this; // our (old) resources get destroyed with x
}
It is said that we should write assignement operator with argument by value rather than by const reference for copy ellision consideration.
With Rvalue reference feature, is it better to write assignement operator like below ? :
T& operator=(T&& x)
{
swap(*this, x);
return *this;
}
there is finally no difference ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
某些类型在交换/分配习惯用法方面比其他类型做得更好。这是一个做得不太好的:
这是我的机器的结果:
我的观点:不要陷入相信灵丹妙药或“做所有事情的唯一正确方法”的陷阱。复制/交换的说法已经被过度宣传了。有时是适当的。但它并不总是合适的。仔细的设计和仔细的测试是无可替代的。
Some types do better with the swap/assign idiom than others. Here's one that doesn't do well:
Here are results off of my machine:
My point: Don't fall into the trap of believing in a silver bullet, or the "one right way to do everything". And the copy/swap idiom is way oversold. It is sometimes appropriate. But in no way is it always appropriate. There is no substitute for careful design, and careful testing.
您想要对副本进行操作,否则您将从原始对象中删除信息。这个想法是从临时副本中删除信息。它不是很直观,但它允许您使用现有的复制构造函数和析构函数实现来完成
op=
的艰苦工作。复制省略是不相关的,因为当语义上需要复制时它无法执行。
对右值引用进行操作可能没问题,因为如果您使用右值表达式作为 RHS 操作数来调用
op=
,那么它可能是一个临时对象和调用范围可能不想/不需要再使用它了。但是,您的op=
不应该承担这样的假设。你的中间方法是规范的。
You want to operate on a copy, otherwise you're removing information from your original object. The idea is to remove information from a temporary copy. It's not highly intuitive but it allows you to use the existing copy constructor and destructor implementations to do the hard work of
op=
.Copy elision is not relevant, because it can't be performed when a copy is semantically required.
Operating on an rvalue reference might be ok, because if you're calling
op=
with an rvalue expression as the RHS operand, then it's probably a temporary object and the calling scope probably doesn't want/need to use it any more. However, it's not yourop=
's job to assume that.Your middle approach is canonical.
这并不是更好,因为这两个运算符是不同的(请参阅五规则)。
第一个 (
T& T::operator=(T const& x)
) 用于分配左值,而第二个 (T& operator=(T&& x)< /code>) 用于 r 值。请注意,如果您只实现了第二个,则这将无法编译:
It is not better, since these two operators are different (see rule of five).
The 1st (
T& T::operator=(T const& x)
) is for assigning l-values, while the 2nd (T& operator=(T&& x)
) is for r-values. Take a note that this would fail to compile if you had only the 2nd implemented :