簡體   English   中英

我應該在移動ctors /賦值運算符中使用std :: move或std :: forward嗎?

[英]Should I use std::move or std::forward in move ctors/assignment operators?

除非我錯了,否則它們似乎都運行得很好 - 是否有一個最佳實踐理由更喜歡一個而不是另一個?

例:

struct A
{
    A(){}
    A(const A&){ std::cout << "A(const A&)\n"; }
    A(A&&){ std::cout << "A(A&&)\n"; }
};

struct B
{
    B(){}
    B(const B& right) : x(right.x){ std::cout << "B(const B&)\n"; }
    B(B&& right) : x(std::forward<A>(right.x)){ std::cout << "B(B&&)\n"; }

    A x;
};

struct C
{
    C(){}
    C(const C& right) : x(right.x){ std::cout << "C(const C&)\n"; }
    C(C&& right) : x(std::move(right.x)){ std::cout << "C(C&&)\n"; }

    A x;
};

struct D
{
    D(){}
    D(const D& right) : x(right.x){ std::cout << "D(const D&)\n"; }
    D(D&& right) : x(right.x){ std::cout << "D(D&&)\n"; }

    A x;
};

int main()
{
    std::cout << "--- B Test ---\n";
    B b1;
    B b2(std::move(b1));
    std::cout << "--- C Test ---\n";
    C c1;
    C c2(std::move(c1));
    std::cout << "--- D Test ---\n";
    D d1;
    D d2(std::move(d1));
}

輸出:

--- B Test ---
A(A&&)
B(B&&)
--- C Test ---
A(A&&)
C(C&&)
--- D Test ---
A(const A&)
D(D&&)

問題是:那些真的是類的移動構造函數/賦值運算符嗎? 或者他們只是從你的眼角看起來像那樣?

struct X{
  X(X&&); // move ctor #1

  template<class T>
  X(T&&); // perfect forwarding ctor #2

  X& operator=(X&&); // move assignment operator #3

  template<class T>
  X& operator=(T&&); // perfect forwarding ass. operator #4
};

真正的移動ctor(#1)和移動賦值運算符(#3)中,你永遠不會使用std::forward ,因為正如你正確評估的那樣,你將永遠移動。

請注意,沒有完美的轉發模板( T&& ), std::forward永遠不會有意義。 這正是#2和#4的情況。 在這里,你永遠不會使用std::move ,因為你不知道你是否真的得到了右值(A-OK)或左值(不是那么多)。

請參閱我的這個答案,了解std::forward實際上是如何工作的。

暫無
暫無

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

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