23

右辺値参照と転送参照の違いは、Scott Meyers によるこの例で十分に明確にされました。

Widget&& var1 = someWidget;     // here, “&&” means rvalue reference (1)

auto&& var2 = var1;             // here, “&&” does not mean rvalue reference (2)

template<typename T>
void f(std::vector<T>&& param); // here, “&amp;&” means rvalue reference (3)

template<typename T>
void f(T&& param);              // here, “&amp;&”does not mean rvalue reference (4)

本質的に区別は、推定可能なコンテキストがある場合に発生します。したがって、ケース (3) は、ケース (4) が推定され、(参照崩壊規則を適用した後) 「値カテゴリ」の観点から分類されることを明示的に示していvector<...>&&ます。T

しかし、もう少し複雑なパターン マッチングではどうなるでしょうか。たとえば、次の場合を考えてみましょう。

template <template <class...> class Tuple, class... Ts>
void f(Tuple<Ts...>&& arg)
{

}

こことは&&どういう意味ですか?

4

3 に答える 3

17

最後の例でargは、右辺値参照です。

転送参照は、cv 修飾されていないテンプレート パラメーターへの右辺値参照です。

Tuple<Ts...>あり、テンプレート パラメータではありません。

([temp.deduct.call] からの引用。)

于 2016-11-26T14:00:29.117 に答える
11

これは転送参照ではなく右辺値参照です。

確認する最も簡単な方法は、左辺値を渡そうとすることです。失敗した場合は右辺値参照になり、そうでない場合は転送参照になります。

template<typename... Ts>
struct foo {};

//f function definition

int main() {
    foo<int, double> bar;
    f(bar); // fails! Cannot bind lvalue to rvalue reference
    f(foo<int, double>{}); // ok, rvalue is passed
}
于 2016-11-26T14:01:15.937 に答える
4

概念転送参照は標準的な概念ではありません。見たときにそれを認識するのに役立ちますが、それを正しく理解して処理するには、参照演算を理解する必要があります。(マイヤーの本にもそれに関する章があると思います)

転送参照の概念の背後にあるのは、参照演算です。

  • && && = &&
  • && & = &
  • & && = &
  • & & = &

転送参照を使用して、コンパイラ テンプレートの型推定をシミュレートしてみましょう

template<class T>
void foo(T&&);
//...
const int i=42;
foo(i); // the compiler will defines T = const int &
         //          T&&  = const int & && = const int &
         // => the compiler instantiates void foo<const int &>(const int &);
foo(6*7);// the compiler will defines T = int
         //          T&&  = int &&
         // the compiler instantiates  void foo<int>(int &&);

このような状況では、テンプレート foo のインスタンス化は、左辺値参照によって引数を取る関数、または引数右辺値参照を取る関数を生成できます: 転送参照は、テンプレートの型推定に応じて、右辺値参照または左辺値参照のいずれかになります。このような状況では、パラメーターは左辺値または x 値として渡されるため、このような名前が付けられています。T&& std::forward<T>(T&& a)

関数に次のものがあると宣言した場合:

 template<class T>
 void foo(ATemplateClass<T> && a);

コンパイラによって T に対して推定される型が何であれ、右辺値参照パラメーターを取得します。

于 2016-11-27T23:41:43.093 に答える