2016-08-07 6 views
15

Scottの最後のマスターピースのC++ 11と14に関する普遍的なリファレンスについては、lvalueまたはrvalueのいずれかの型に割り当てられているにもかかわらず参照パラメータには、通過した引数の型特性に基づいてl/rvalueに推論できる汎用参照の間に何かがあります。私は右辺値としてのpを作るもの普遍的な基準として、パラメータになりますが、typeパラメータconst T&& pへのconstを追加する理由は私にはクリアされない一つのことは理解できますなぜ `const`を追加すると汎用の参照がrvalueになるのですか

template<typename T> 
void f(T&& param); // param is an universal reference 

template<typename T> 
void f(const T&& param); // param is an rvalue reference 

constは、以上のことをしていこれは参照パラメータに割り当てられます。

答えて

11

正式名称は普遍的な参照ではなく、forwarding referenceです。

関数呼び出し[temp.deduct.call]

3からテンプレート引数を推測

14.8.2.1:CV-修飾されていないテンプレートパラメータにのみ右辺値参照はこのカテゴリーに入るStandard状態Pがcv修飾型である場合、P型の最上位のcv修飾子 は型減算のために無視されます。 Pが参照型の場合は、Pで参照される型 が型減算に使用されます。 フォワーディングリファレンスは cv-unqualifiedテンプレートパラメータへの参照値です。 Pが 転送参照で、引数が左辺値の場合は、タイプ控除ではAの代わりに "lvalue A"を使用します。 [例:

template <class T> int f(T&& heisenreference); 
template <class T> int g(const T&&); 
int i; 
int n1 = f(i); // calls f<int&>(int&) 
int n2 = f(0); // calls f<int>(int&&) 
int n3 = g(i); // error: would call g<int>(const int&&), which 
       // would bind an rvalue reference to an lvalue 

- 終了例] const T&&はとして転送参照を動作するように許可

は、それが不可能なパラメータとしてのみ右辺値参照を取るテンプレート関数をオーバーロードすることになるだろう。

更新は:@HowardHinnantコメントに言及して、const T&&は、その用途を持っている(またthis Q&A参照)。

+1

OPを混乱させた_Effective Modern C++ _のItem 24の部分に戻って、スコットは、型推論の文脈の中でrvalue参照となる(ゆるく)普遍的な参照を記述する_。上記の14.8.2.1標準引用符の最初の(強調されていない)文(_ "Pがcv修飾型であれば、P型の最上位レベルのcv修飾子**は型控除**" _のために無視されます) 「「const」修飾子の単純な存在でさえも、参照が普遍的であることから不適格とするには十分であるというスコットの声明を説明している。_(本からの引用、項目24) – dfri

+1

@dfriありがとう、私は近くにEMC++のデジタルコピーを持っていなかった。 – TemplateRex

+2

その理由についてもっと動機づけることがあります:時々、私たちは言うべきことがあります:左辺値にのみバインドしないでください: 'template void cref(const T &&)= delete;'。 –

関連する問題