簡體   English   中英

C ++ 11移動構造函數優化

[英]C++11 Move constructor optimization

我目前正試圖抓住移動構造函數。 我發現了以下內容(使用g++ d.cpp --std=c++11 -O3編譯g++ d.cpp --std=c++11 -O3

class A {
    string _x;
public:
  A(string x) { cout << "default contrsutctor: " << x << "\n"; _x = x; }
  A(const A& other) { cout << "copy contrsutctor: " << other._x << "\n"; _x = other._x;  }
  A(A&& other) { cout << "move contrsutctor: " << other._x << "\n"; _x = other._x;  }

  A foo() {
    cout << "foo: " << _x << "\n";
    return A("foo");
  }
};

int main()
{
  A a;
  A b = a;
  b.foo();
}

我希望這輸出:

default contrsutctor: a
move contrsutctor: a
foo: a
default contrsutctor: foo

但輸出是:

default contrsutctor: a
copy contrsutctor: a
foo: a
default contrsutctor: foo

為什么不使用移動構造函數優化A b = a線? 之后永遠不會使用a對象,因此優化代碼以使用它而不是復制構造函數是安全的。

我知道我可以強制使用std::move()來調用move構造函數,但是我希望在這樣的情況下自動執行此操作。

為什么不使用移動構造函數優化A b =一條線?

您可以在復制構造函數和移動構造函數中執行的操作可能完全不同。 編譯器無法保證兩個構造函數的結果相同。 實現這種優化有可能改變程序的行為,從而破壞了as-if規則

您需要使用std::moveaA&&

#include <utility>
int main()
{
  A a("a");
  A b = std::move(a);
  b.foo();
}

移動構造函數的正確實現應該是:

A(A&& other)
: _x(std::move(other._x))
{}

A b = std::move(a); a應該是“空的”。 在這種情況下, a._x將為空。 正如@TonyD在評論中指出的那樣, a._str可能處於未指定但有效的狀態( 移動std:string的構造函數 )。 你應該使用a該行后慎用。

A b = a; 總是調用復制構造函數,無論它是否可以調用移動構造函數。 此外,對象a的生命周期在分配后繼續,即使它不再使用。

如果要使用移動構造函數,則必須將其顯式化:

A b = std::move(a);

請注意,這可能是危險的,作為a仍然在移動后訪問。 如果您以后不小心使用它,可能會有未定義的行為。

想想為什么它應該自動發生。 在你給出的例子中,沒有必要,因為你可以使用a代替b 在許多情況下,它會更有意義移動構造函數/賦值將自動使用,例如A a; a = foo(); A a; a = foo();

為什么不使用移動構造函數優化A b =一條線?

因為這會改變程序的可觀察行為。 除非在特定情況下(§12.8/ 31),否則不允許編譯器自由更改程序的可觀察行為(§1.9/ 1)。 這不是其中之一。 從構造函數中刪除副作用,編譯器可能會優化它們。 當然,如果刪除副作用,那么你將不會注意到編譯器是否優化了構造函數的調用(除非你檢查匯編或二進制輸出),但這就是重點。

暫無
暫無

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

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