簡體   English   中英

何時不使用帶有r值的std :: forward?

[英]When not to use std::forward with r-values?

什么情況下不需要std::forward 它用於包裝內部函數參數,它是templated-rvalue(也就是說,它可以是lvalue或named-rvalue)。 像:

template<class T>
void outer(T&& t) { 
    inner(std::forward<T>(t)); 
}

我猜一個案例是當內部函數參數按值傳遞時。 還有其他情況嗎? 當我寫std::begin(std::forward<Ct>(ct))時,我有這個問題,其中Ct是templated-rvalue-ref。

編輯可能的重復

如果我沒記錯的話,這是第三次嘗試將這個4歲的問題關閉,因為一些不了解這個問題的新手。

“使用前鋒的好處?” 和“何時不使用帶有r值的std :: forward?” 是非常不同的問題。 首先介紹初學者的r值,然后討論高級C ++用戶的完美轉發。 我是元模板庫和lambda庫的作者,他們不需要詳細的基礎知識描述。 答案中的信息與其他問題有很大不同。

當模板參數類型包含值類別時,可以進行完美轉發。 (如果這句話沒有意義,請花一點時間熟悉手頭的問題 。)

鑒於:

template <typename T>
void foo(T&& x); 

foo的主體內, T將采用UU&的形式。 前者意味着我們通過了右值,后者意味着我們通過了左值。 我們可以像這樣轉發這個事實:

template <typename T>
void foo(T&& x)
{
    bar(std::forward<T>(x));
}

將左值傳遞給foobar獲得相同的左值。 將rvalue傳遞給foobar獲得rvalue。

如果您無法區分值類別,那么轉發是沒有用的。 只有當您使用與上述相同的方式推導出模板參數時,它才有用。 是的,它在這里沒用:

template <typename T>
void foo(const T& x)
{
    // if this was called as foo(1), we're none the wiser
}

我正在回答我自己的問題,因為到目前為止我沒有得到滿意的答復。 如果我能得到甚至很小的改進/補充 - 我會選擇你接受的答案。

一般來說,如果實現完美轉發的效果, std::forward將對內部功能有益。 否則它是多余的。

僅當以下任何一個為真時,才使用std::forward來包裝內部函數arg:

  • 內部函數參數是templated-rvalue-ref(現在稱為“轉發引用”);
  • 內部函數有多個重載,它們根據參數r / l-valueness進行區分;
  • 內部函數有多個重載,它們根據constness區分lvalue參數;

使用std :: forward(在形式參數上對模板化函數,其類型為T &&形式,T為模板的類型參數):

  • 當內部函數調用是外部函數中最后一次使用參數時,和
  • 當內部函數的可能重載可能會或可能不會將參數作為右值引用時。

基本原理是,當一個對象可能通過rvalue引用作為參數傳遞時(這是你允許使用std :: forward),它的信息內容可能會被破壞。 因此,當您確定不再使用該信息內容時,您只想這樣做。

例:

#include <utility>

template <class T> void f(T &&t);
template <class T> void g(const T &t);

template <class T>
void outer(bool f_first, T &&t)
  {
    if (f_first)
      {
        f(t);
        g(t);
      }
    else
      {
        g(t);
        f(std::forward<T>(t));
      }
  }

#include <string>

void foo(std::string s)
  {
    outer(true, s);
    outer(true, s + "x");
    outer(false, s);
    outer(false, std::move(s));
  }

暫無
暫無

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

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