簡體   English   中英

使用std :: forward而不是std :: move初始化對象有什么好處嗎?

[英]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::bindcppreference文檔說明綁定對象“持有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可以消除額外對象的創建。

如果您不使用轉發引用,則涉及三個對象:

  1. 來電者的原始對象
  2. 函數參數f ,根據需要使用復制或移動構造函數構造
  3. 綁定對象的內部對象,由移動構造函數構造

如果您使用帶有std::forward的轉發引用,則會消除第二個引用。 只會創建兩個對象:

  1. 來電者的原始對象
  2. 綁定對象的內部對象,根據需要使用復制或移動構造函數構造

移動構造對象可能比復制構造(取決於類型)便宜,但它仍然會帶來一些完美轉發可以避免的開銷。

暫無
暫無

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

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