簡體   English   中英

復制賦值運算符是否建議使用復制和交換習慣用法以及自我分配檢查?

[英]Is copy assignment operator with copy and swap idiom and self assignment check recommended?

在這里,您可以看到自我分配檢查的復制賦值運算符實現:

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;
}

這對於自我分配很有用,但對性能有害:

  1. 因為每次檢查就好如果聲明(我不知道它會是多少最佳,考慮到分支預測)
  2. 我們也失去了rvalue參數的復制省略

所以我仍然不明白我是否會實現std::vectoroperator=我將如何實現它。

是的,這段代碼是超級的。 確實,它正在造成額外的不必要的分支。 通過適當的交換和移動語義,以下應該更高性能:

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;
}

另請注意,按值接受參數更為有益。

因為每次檢查就好如果聲明(我不知道它會是多少最佳,考慮到分支預測)

我想你在這里已經處於一個過早的優化圈。

檢查自我分配 - >如果正確編寫代碼,則不需要自我分配 - >為什么不明確地寫swap - >我們回到原點

實際上,我只是實現Allocator而不用擔心它。

我們也失去了rvalue參數的復制省略

我不這么認為。

#include <iostream>

#define loud(x) std::cout << x << "\n";

struct foo
{
    foo() { loud("default") }
    ~foo() { loud("destruct") }

    foo(const foo&) { loud("copy") }
    foo(foo&&) { loud("move") }

    foo & operator=(const foo & s)
    {
        if (this != &s)
        {
            loud("copy assign")
        }

        return *this;
    }
};

int main()
{
    foo f;
    foo g;
    g = f;
}

輸出:

default
default
copy assign
destruct
destruct

這是-fno-elide-constructors


你聲稱分支可能有問題,但-O2的匯編輸出顯示GCC甚至沒有為operator=發出代碼,只是直接輸出"copy assign"字符串。 是的,我意識到我有一個簡化的例子,但它確實是從一開始的錯誤結束。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM