web-dev-qa-db-ja.com

ユニバーサル参照と転送参照に違いはありますか?

この関数の引数は右辺値参照にバインドします:

void f(int && i);

ただし、この関数の引数は右辺値または左辺値参照のいずれかにバインドされます。

template <typename T>  
void f(T && t);

これは普遍的なリファレンスと呼ばれることをよく耳にします。
転送参照とも呼ばれています。
同じ意味ですか?
関数本体がstd::forward

33
Trevor Hickey

同じ意味ですか?

niversal reference は、スコットマイヤーズがcv非修飾テンプレートパラメーターへの右辺値参照を取得する概念を説明するために造語した用語で、値または左辺値参照のいずれかとして推測できます。

当時、C++標準にはこれに関する特別な用語がありませんでした。これはC++ 11の見落としであり、教えるのが難しくなります。この見落としは N4164 によって修正され、次の定義が [temp.deduct] に追加されました。

転送参照は、cv-unqualifiedテンプレートパラメータへの右辺値参照です。 Pが転送参照であり、引数が左辺値である場合、型推定のためにAの代わりに「左辺値参照」型が使用されます。

したがって、2つは同じことを意味し、現在のC++標準用語は転送参照です。論文自体は、「転送参照」が「普遍的な参照」よりも優れた用語である理由を明確にしています。

関数本体がstd::forwardを呼び出す場合、それは転送参照のみですか?

いいえ、転送参照で行うことは名前とは無関係です。転送参照の概念は、タイプTがどのように推測されるかを単に示しています。

template <class T> void foo(T&& ); // <== 

後で転送する必要はありません。

42
Barry

残念ながら、混乱を招きますが、同じものの2つの名前にすぎません。
普遍的な参照は、ずっと前にマイヤーズによって提案された(推測する)(例として here を参照)。
転送参照は、standardeseから直接選択されます。それで全部です。

14
skypjack