应该在什么情况下使用lvalue / rvalue重载来实现operator =而不是copy-and-swap?

时间:2013-10-22 16:38:08

标签: c++ c++11 rvalue-reference

正如https://stackoverflow.com/a/3279550/943619所描述的那样,实施operator=的正确方法通常是:

my_type& operator=(my_type other) {
    swap(*this, other);
    return *this;
}
friend void swap(my_type& lhs, my_type& rhs) { ... }  // This can vary some.

然而,Howard Hinnant指出,通过为左值和右值参数实现单独的重载,有时可以做得更好:

my_type& operator=(const my_type& other) { ... }
my_type& operator=(my_type&& other) { ... }

显然,在多种情况下,2次过载解决方案可以节省一次移动,但这种小幅改进不太可能出现在基准测试中。相反,我正在寻找能够将性能提高一倍的情况。

1 个答案:

答案 0 :(得分:1)

“复制和交换”习惯用语的主要问题是效率较低。

即使我们有一个很好的swap实现,我们仍然同时有3个类的实例,其中lvalue和rvalue运算符的另一个解决方案只有2个实例。

这意味着我们需要50%的内存来进行复制和交换,并且它可能也会花费大量的时间 - 因为您必须获得本来不需要的资源。

考虑std::vector案例:如果您vec1=vec2;并且两者具有相同的大小,则使用左值引用 - 您不需要执行任何new和{{1}完全没有。在复制和交换中,你必须创建第三个向量 - 所以你有一个额外的deletenew可能需要花费很多时间(如果向量很小,那么它很重要)或者大量的记忆(如果向量很大)

复制和交换的主要优点是异常安全。 copy-and-swap为您提供强大的异常安全性,但代价是性能。

如果您需要异常安全 - 请使用它。如果您需要性能(内存,时间,您的课程所需的任何其他资源),请不要使用它。