5

http://thbecker.net/articles/rvalue_references/section_08.htmlstd::forwardがどのように機能するかについてのこの説明から理解できる限り、次の 1 つのバージョンのみを省くことができます。std::forward

template<class S>
S&& forward(typename remove_reference<S>::type& a) noexcept

しかし実際には、( http://en.cppreference.com/w/cpp/utility/forward ) 2 番目のバージョンがあります。

template< class T >
T&& forward( typename std::remove_reference<T>::type&& t );

tの定義方法のみが前のものと異なります(with &&)

では、なぜそれが必要なのでしょうか? 外すと何が壊れますか?

4

1 に答える 1

5

オーバーロードへの引数std::forward( を使用std::remove_reference) は、それ以外の場合に発生する参照の崩壊と引数の推定を削除し、左辺値と右辺値の参照を正しいオーバーロードに強制的にバインドします。constこれは、元の引数の一部 (または一部ではない) の可能性を追加または削除せずに行われますT(つまり、 a を使用しない右辺値にconst T&a を追加するため、 aを使用しませんが、どちらも a にバインドできます同じ右辺値)。constT&&

キー エラー チェックは、右辺値参照のオーバーロードで行われます。std::forward右辺値が提供されたときに左辺値参照に転送するために が呼び出されないようにするための健全性チェックです。基本的に、次のようなコードstd::forward<int&>(42);がコンパイルに失敗することを確認してください。は、参考文献に記載されているように、推論されたコンテキストからの式でstd::forward使用されることを意図しています。オーバーロードは、必要なエラー チェックを伴う条件付きリターンと同じ結果をもたらします。std::forward<T>TT&&

の実装std::forwardは、Scott Meyers がGoing Native 2013の講演で語っている「条件付きキャスト」を対象としています。std::forwardScott Meyers は、彼のプレゼンテーションで(約 20 分の時点で)の動作を説明するために、次の疑似コードを示しています。

template <typename T>
T&& forward(T&& param) { // T&& here is formulated to disallow type deduction
  if (is_lvalue_reference<T>::value) {
    return param; // return type T&& collapses to T& in this case
  }
  else {
    return move(param); // return type is T&&
  }
}

std::forwardは、引数の型が左辺値の場合は左辺値参照を返し、引数の型の型が右辺値のstd::move場合は右辺値参照 ( と同等) を返すように実装されています。


TL;DR なぜそれが必要なのですか? 基本的; の誤った使用から保護しますstd::forward(たとえば、ダングリング参照、使用できなくなった一時オブジェクトへの参照、変更/変更されたリテラルなど)。

于 2014-08-05T10:55:36.847 に答える