复制赋值运算符是否建议使用复制和交换习惯用法以及自我分配检查?

Nar*_*rek 5 c++ stdvector copy-assignment c++11

在这里,您可以看到自我分配检查的复制赋值运算符实现:

String & operator=(const String & s)
{
    if (this != &s)
    {
        String(s).swap(*this); //Copy-constructor and non-throwing swap
    }

    // Old resources are released with the destruction of the temporary above
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

这对于自我分配很有用,但对性能有害:

  1. 因为每次检查就好如果声明(我不知道它会是多少最佳,考虑到分支预测)
  2. 我们也失去了rvalue参数的复制省略

所以,我还是不明白,如果我想实现std::vectoroperator=我将如何实现它.

Ser*_*eyA 5

是的,这段代码是超级的.确实,它正在造成额外的不必要的分支.通过适当的交换和移动语义,以下应该更高性能:

String& String::operator=(String s) { // note passing by value!

    std::swap(s, *this); // expected to juggle couple of pointers, will do nothing for self-assingment
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

另请注意,按值接受参数更为有益.

  • @SergeyA:一般来说,你应该避免显式调用`std :: swap`.使用`using std :: swap; swap(a,b)`允许在ADL期间找到交换重载,或者`boost :: swap`为你做这个,或者`std :: iter_swap(&a,&b)`也可以这样做.出于这个原因,自定义交换函数应该在与该类相同的命名空间中定义为友元函数. (3认同)
  • @Zereges,我的观点是实际的自我约束不会经常发生(至少在我的代码中).因此,对于temoraries的复制省略非常重要 - 而且此代码允许这样做. (3认同)
  • @SergeyA:特别参见http://stackoverflow.com/a/8439357/87234.tl; dr:ADL-found swap始终有效(只要交换器总是允许找到ADL交换,标准需要它自己的实现),std :: swap专门化并不总是有效. (2认同)