我看到這個在這裏的std ::移動和性病的區別: Move Constructor calling base-class Move Constructor什麼::向前
有人能解釋一下:
std::move
和std::forward
之間的區別,最好用一些代碼的例子嗎?- 如何去想它很容易,當要使用的
我看到這個在這裏的std ::移動和性病的區別: Move Constructor calling base-class Move Constructor什麼::向前
有人能解釋一下:
std::move
和std::forward
之間的區別,最好用一些代碼的例子嗎?std::move
需要一個對象,並允許您將其視爲臨時(右值)。雖然它不是一個語義要求,但通常接受對右值的引用的函數將使其無效。當您看到std::move
時,表示該對象的值不應該在以後使用,但仍可以分配一個新值並繼續使用它。
std::forward
有一個用例:將模板函數參數(在函數內部)強制轉換爲調用者用來傳遞它的值類別(左值或右值)。這允許右值參數作爲右值傳遞,左值作爲左值傳遞,稱爲「完美轉發」。
void overloaded(int const &arg) { std::cout << "by lvalue\n"; }
void overloaded(int && arg) { std::cout << "by rvalue\n"; }
template< typename t >
/* "t &&" with "t" being template param is special, and adjusts "t" to be
(for example) "int &" or non-ref "int" so std::forward knows what to do. */
void forwarding(t && arg) {
std::cout << "via std::forward: ";
overloaded(std::forward<t>(arg));
std::cout << "via std::move: ";
overloaded(std::move(arg)); // conceptually this would invalidate arg
std::cout << "by simple passing: ";
overloaded(arg);
}
int main() {
std::cout << "initial caller passes rvalue:\n";
forwarding(5);
std::cout << "initial caller passes lvalue:\n";
int x = 5;
forwarding(x);
}
如霍華德提到,也有相似之處這兩個函數簡單地轉換爲引用類型。但是,這些特定的用例(其中包括右值引用類型轉換的有效性的99.9%)外,你應該直接使用static_cast
,寫的你在做什麼了很好的解釋。
我不確定'std :: forward'的_only_用例是函數參數的完美轉發。我遇到了想要完美轉發其他內容的情況,例如對象成員。 – 2013-12-11 16:53:44
@GeoffRomer參數的成員?你有一個例子嗎? – Potatoswatter 2013-12-11 23:11:51
我張貼的例子作爲一個單獨的問題:http://stackoverflow.com/questions/20616958/stdforward-without-perfect-forwarding – 2013-12-16 23:47:51
std::forward
用於向前參數正是它被傳遞給函數的方式。就像這裏顯示:
When to use std::forward to forward arguments?
使用std::move
提供了一個對象作爲右值,以匹配可能一招構造或接受右值的函數。即使x
本身不是一個右值,它也可以用於std::move(x)
。
std::forward
和std::move
都不過是表演。
X x;
std::move(x);
上述投射型X的左值表達式x
到X型(一個x值是精確的)的右值表達。 move
還可以接受右值:
std::move(make_X());
,並在這種情況下,它是一種身份的功能:採用X型的右值,並返回一個類型X的右值
隨着std::forward
可以選擇目的地一定程度:
X x;
std::forward<Y>(x);
施放類型X的左值表達式x
到類型Y的表達上有Y可以是什麼限制。 Y可以是X的可訪問的基礎,或者是對X的基礎的引用。Y可以是X或對X的引用。不能用forward
來拋棄cv限定符,但可以添加cv-預選賽。 Y不能是隻能從X轉換的類型,除非通過可訪問的Base轉換。
如果Y是一個左值引用,則結果將是一個左值表達式。如果Y不是左值引用,結果將是一個右值(xvalue是精確的)表達式。
forward
只有當Y不是左值引用時才能取右值參數。也就是說,你不能左值左值。這是出於安全原因,因爲這樣做通常會導致懸掛引用。但是將右值賦給右值是可以的,並且是允許的。
如果您嘗試將Y指定爲不允許的內容,則錯誤將在編譯時捕獲,而不是在運行時捕獲。
如果我完美地使用'std :: forward'將一個對象轉發給函數,那麼在該函數執行後,我可以使用該對象嗎?我知道,在std :: move的情況下,這是一個未定義的行爲。 – iammilind 2017-12-26 11:32:49
關於'move':https://stackoverflow.com/a/7028318/576911對於'forward',如果你在一個左值傳遞,你的API應該如果它收到一個左值反應。通常這意味着該值將不被修改。但是,如果它是非常量左值,那麼您的API可能已經對其進行了修改。如果你傳入一個右值,這通常意味着你的API可能已經從它移出,並且因此將應用https://stackoverflow.com/a/7028318/576911。 – 2017-12-26 15:29:54
也看到這兩個相關的問題:我應該使用std ::移動或std中移動構建函數/賦值運算符::前鋒?](http://stackoverflow.com/q/8860233/500104)和[如何std :: forward work?](http://stackoverflow.com/q/8526598/500104)(以及重複的問題)。 – Xeo 2012-03-12 17:34:44
「如何輕鬆地考慮它,以及何時使用」當你想要*移動*值時使用'移動',當你想使用完美的轉發時使用'前進'。這裏不是火箭科學;) – 2012-03-12 17:47:02
move()執行無條件轉換,其中forward()根據傳遞的參數執行轉換。 – 2016-05-18 12:24:43