[英]Is there any benefit in using std::forward instead of std::move to initialize an object?
我有一個函數模板,它接受一些可調用類型的參數,並使用std::bind
創建一個新的可調用對象,其中包含原始可調用的預定義參數值。 我用轉發引用參數和std::forward
編寫了它,如下所示:
template <typename F>
auto make_example_caller(F &&f) {
return std::bind(std::forward<F>(f), 123, 456, 789);
}
std::bind
的cppreference文檔說明綁定對象“持有std::decay<F>::type
的成員對象,從std::forward<F>(f)
構造”。 由於std::bind
將函數轉發給其內部數據成員,因此在我自己的代碼中將相同的函數轉發給std::bind
調用似乎是合理和合適的。
但是,目前尚不清楚它帶來了什么好處。 如果F
是引用類型,則std::decay
將刪除引用,因此綁定對象將存儲其自己的可調用類型實例。 如果F
是右值引用,那么該實例將被構造為移動,如果F
是左值,則該實例將被構造為副本,如果我像這樣編寫我的函數,我可以獲得相同的結果:
template <typename F>
auto make_example_caller(F f) { // Note, no &&
return std::bind(std::move(f), 123, 456, 789); // move, not forward
}
現在我的函數自己的f
參數將根據函數的調用方式通過移動或復制進行初始化,但無論哪種方式,我現在都有自己的函數對象實例,我可以將其移動到綁定對象中。
后一種方式似乎更簡單,但我想知道我是否遺漏了某些東西 - 特別是因為相同的推理將適用於std::bind
本身,但它需要一個F&&
並轉發它,而不是取值F
並移動它。 這樣做有不利之處嗎? 我沒見過的東西?
使用轉發引用和std::forward
可以消除額外對象的創建。
如果您不使用轉發引用,則涉及三個對象:
f
,根據需要使用復制或移動構造函數構造 如果您使用帶有std::forward
的轉發引用,則會消除第二個引用。 只會創建兩個對象:
移動構造對象可能比復制構造(取決於類型)便宜,但它仍然會帶來一些完美轉發可以避免的開銷。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.