7

不要な場合 std::forwardはどうなりますか?これは、templated-rvalueである内部関数引数をラップするために使用されます(つまり、lvalueまたはnamed-rvalueにすることができます)。のように:

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

1つのケースは、内部関数パラメーターが値によって渡される場合だと思います。他にケースはありますか?std::begin(std::forward<Ct>(ct))Ctがtemplated-rvalue-refである場所を書いているときに、この質問があります。

重複の可能性について編集

私の記憶が正しければ、これは、この4年前の質問を、質問を理解していない初心者が複製したものとして閉じる3回目の試みです。

「フォワードを使用する利点は?」および「r値でstd::forwardを使用しない場合は?」非常に異なる質問です。1つ目は、初心者向けのr値の紹介であり、2つ目は、上級C++ユーザー向けの完全な転送についての説明です。私はメタテンプレートライブラリとラムダライブラリの作成者であり、基本の詳細な説明は必要ありません。回答の情報は他の質問とは大きく異なります。

4

3 に答える 3

6

テンプレートパラメータタイプに値カテゴリが含まれている場合、完全な転送が可能です。(この文が意味をなさない場合は、目前の問題に慣れるために少し時間を取ってください。)

与えられた:

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

の本体内ではfoo、またはTのいずれかの形式を取ります。前者は右辺値が渡されたことを意味し、後者は左辺値が渡されたことを意味します。この事実を次のように転送できます。UU&

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

左辺値をに渡し、同じ左辺値を取得しますfoobarに右辺値を渡し、右辺値をfoo取得barします。

値のカテゴリを区別できない場合、転送は役に立ちません。上記と同じ方法で推定されるテンプレートパラメータがある場合にのみ役立ちます。そうです、ここでは役に立ちません。

template <typename T>
void foo(const T& x)
{
    // if this was called as foo(1), we're none the wiser
}
于 2012-08-21T05:47:54.307 に答える
3

今のところ満足のいく答えが得られなかったので、私は自分の質問に答えています。私がこれに少しでも改善/追加を得るならば-私はあなたの答えを受け入れられたものとして選びます。

一般に、完全な転送の効果が達成されるstd::forward場合、内部機能で有益になります。それ以外の場合は不要です。

std::forward以下のいずれかが当てはまる場合にのみ、内部関数argをラップするために使用します。

  • 内部関数パラメーターはtemplated-rvalue-ref(現在は「転送参照」と呼ばれています)です。
  • 内部関数には、パラメーターr/l値に基づいて区別される複数のオーバーロードがあります。
  • 内部関数には、定数に基づいて左辺値パラメーターを区別する複数のオーバーロードがあります。
于 2012-08-26T05:42:10.133 に答える
-1

std :: forwardを使用します(テンプレート化された関数への正式なパラメーターで、その型はT &&の形式であり、Tはテンプレートの型パラメーターです):

  • 内部関数呼び出しが外部関数のパラメーターの最後の使用である場合、および
  • 可能であれば、内部関数のオーバーロードは、パラメーターを右辺値参照として受け取る場合と受け取らない場合があります。

理論的根拠は、オブジェクトが右辺値参照(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));
  }
于 2016-10-29T23:37:07.460 に答える