他の人が言ったことにもかかわらず、標準は右辺値参照についてのみ話します。
これが std::move でどのように機能するかの鍵は、テンプレート引数推定の規則における明示的な特別規則です。
[...] [宣言された関数パラメーター型] が cv 修飾されていないテンプレート パラメーターへの右辺値参照であり、引数が左辺値である場合、型推定のために A の代わりに型「A への左辺値参照」が使用されます。[ ...]
もう 1 つの部分は、参照の崩壊に関するルールです。
[...] 型テンプレート パラメータ [...] が型 T への参照である型 TR を示す場合、型「cv TR への左辺値参照」を作成しようとすると、型「T への左辺値参照」が作成されます。 」、型「cv TR への右辺値参照」を作成しようとすると、型 TR が作成されます。
関数パラメーターでtemplate<class T> typename remove_reference<T>::type&& std::move(T&& a);
は、上記のルール (「cv 非修飾テンプレート パラメーターへの右辺値参照」) に一致するため、引数が左辺値の場合、推定される型は引数の型への左辺値参照になります。あなたの場合、それは T = A& につながります。
それを move の宣言に代入すると、
remove_reference<A&>::type&& std::move<A&>(A& && a);
remove_reference の定義と参照の折りたたみ規則 (TR => TR への右辺値参照) を使用すると、次のようになります。
A&& std::move<A&>(A& a);
Scott Meyer の普遍的な参照の概念は、他の回答で提唱されているように、型推定のルールと参照の崩壊の組み合わせのこの驚くべき効果を思い出すのに役立ちます。推定された型への右辺値参照は左辺値参照になる場合があります型は左辺値参照であると推定される場合があります)。しかし、標準には普遍的な参照はありません。スコット・マイヤーズが言うように: それは嘘です - しかし、真実よりも役立つ嘘です...
std::forward はこのテーマの別のひねりであることに注意してください: 追加の間接化を使用して引数の演繹を防止します (そのため、型を明示的に指定する必要があります) が、参照の折りたたみを使用して、左辺値を左辺値として、右辺値を右辺値として転送します。