2013-10-03 12 views
18

だが、私はこの機能を持っているとしましょう右辺値参照を参照してください。これは正しいです。私はこのようなテンプレート関数にFを変換する場合C++テンプレート関数の挙動

は今:それはそうですなぜ

int x = 5; 
f(x, 5); 

template <class T, class U> 
bool f(T&& one, U&& two) { } 

その後、私は左辺値参照してそれを呼び出すことができますか?この場合、コンパイラはなぜ不平を言っていませんか?

答えて

8

ので、参考崩壊が起こります。スコットマイヤーズはユニバーサルリファレンスと呼んでいます。 U&&は実際にint &になります。どのように動作し、どのように使用できるかについては、article and videoがあります。

6

これは、これらのルールが適用されるテンプレートであるため、Cで添加参照崩壊ルール++ 11

A& & becomes A& 
A& && becomes A& 
A&& & becomes A& 
A&& && becomes A&& 

起こるが、正常な機能において機能で正常崩壊は言及はありません。 auto,decltypeまたはtypedef(それにはusingの宣言が含まれています)のように、参照の折りたたみが発生するような状況があります。コンパイルの結果について説明しています。リファレンスを参照することができないため、A & &などの参照を使用しないと、エラーが発生するため、参照の折りたたみをC++ 11で追加する必要がありました。

+2

「普遍的な参照」の場合に参照縮退が発生しますが、実際の魔法はこのステップの前に発生し、テンプレート引数の控除中に発生します。参照機能の崩壊が正常な機能で動作していないことに注意してください。参照の崩壊はどこでも起こり得る: 'T = int &&; void foo(T & x); 'ここでxは' int 'なので参照が崩壊する – Simple

+0

@Simpleはあなたの右のように見えますが、私はすでにdecltypesとautoが参照崩壊を起こす可能性があることを知っていました。私の答えを修正します – aaronman

10

§8.3.3/6。これは参照縮退ルールです。標準のドラフトから

template <class T> void func(T&&) // Accepts rvalue or lvalue 
void func(T&&)      // Accepts rvalue only 
void func(T&)      // Accepts lvalue only 

ワース例:テンプレート引数控除がある

int i; 
typedef int& LRI; 
typedef int&& RRI; 

LRI& r1 = i;   // r1 has the type int& 
const LRI& r2 = i;  // r2 has the type int& 
const LRI&& r3 = i; // r3 has the type int& 

RRI& r4 = i;   // r4 has the type int& 
RRI&& r5 = 5;   // r5 has the type int&& 

decltype(r2)& r6 = i; // r6 has the type int& 
decltype(r2)&& r7 = i; // r7 has the type int& 
+3

これは逆の直感的なものです... –

+0

@VioletGiraffeはC++の世界へようこそ –

+0

@jk:そして、私はこの世界の大部分を理解していると思っていました! –

関連する問題