3 回答

TA貢獻1831條經驗 獲得超4個贊
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 );
}
正如霍華德(Howard)所提到的,這兩個函數也都具有相似之處,因為它們只是轉換為引用類型。但是,除了這些特定的用例(覆蓋了右值引用強制轉換的99.9%的有用性)之外,您應該static_cast直接使用并為自己的工作寫一個很好的解釋。

TA貢獻1111條經驗 獲得超0個贊
兩者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的引用。一個不能使用放棄cv限定詞forward,但可以添加cv限定詞。Y不能是只能從X轉換的類型,除非通過可訪問的Base轉換。
如果Y是左值引用,則結果將是左值表達式。如果Y不是左值引用,則結果將是右值(精確地說是xvalue)表達式。
forward僅當Y不是左值引用時才可以使用右值參數。也就是說,您不能將右值轉換為左值。出于安全原因,因為這樣做通常會導致懸掛參考。但是將右值轉換為右值是可以的并且可以的。
如果嘗試將Y指定為不允許的值,則錯誤將在編譯時而不是運行時捕獲。

TA貢獻1827條經驗 獲得超4個贊
std::forward用于完全按照傳遞給函數的方式轉發參數。就像這里顯示的那樣:
什么時候使用std :: forward轉發參數?
使用std::move提供對象作為右值,以匹配移動構造函數或接受右值的函數。std::move(x)即使它x本身不是右值,它也會這樣做。
- 3 回答
- 0 關注
- 1661 瀏覽
添加回答
舉報