2009-05-09 11 views
20

今後のC++標準であるC++ 0xのクールな新機能の1つは、「rvalue references」です。C++ 0x rvalueリファレンスがデフォルトでないのはなぜですか?

void FunctionWithLValueRef(int& a) {...} 
void FunctionWithRValueRef(int&& a) {...} 

int main() { 
    FunctionWithLValueRef(5); // error, 5 is a temporary 
    FunctionWithRValueRef(5); // okay 
} 

だから、彼らがした理由:それは(通常、一時的にのみconst参照にバインドすることができます)一時的な値にバインドすることができますことを除いて右辺値参照は、左辺値(正常)を参照に似ています通常の参照の制限を削除して一時的なものにバインドするのではなく、まったく新しい型を考案しますか?

+3

なぜこれが3つの票を得たのだろうと思ったのですか?私はそれを投票せずに質問を好きになったとは思っていません。(私が投票に失敗したり、ロックされていない限り) – Zifre

+3

私はなぜ誰かが何らかの形で考えているのだろうと思っています。 – user534498

+1

私はなぜ「うまくやってアップフォートを与えるの?」が不合理な期待だと思っています。 –

答えて

43

無意味です。あなたは関数内のものを変更し、実際には一時的なものだったので、変更はすぐに失われます。

新しいタイプの理由は、実際に何が評価値であるかを決定する必要があるからです。それだけであなたは実際に彼らが使用されているクールなもののためにそれらを使用することができます。 「あなたには、いくつかの右辺値を持っており、それがTOUPPERに渡す場合、我々は、一時はとにかく使い捨てのものである知っているので、今

string toupper(string && s) { // for nonconst rvalues 
    for(char &c : s) make_uppercase(c); 
    return move(s); // move s into a returned string object 
} 

string toupper(string const& s) { // for the rest 
    // calls the rvalue reference version, by passing 
    // an rvalue copy. 
    return toupper(string(s)); 
} 

は、右辺値を直接変更することができますので、我々はそれとドンを変更するだけでaswellすることができますそれをコピーする必要はありません。また、移動コンストラクターや移動割り当てと呼ばれるものについても同じことが言えます。右手側はコピーされませんが、その物はちょうど盗まれて*thisに移動されます。

右辺値が非左辺値参照にバインドできるとすれば、最後に左辺値(名前付きオブジェクト)または右辺値(一時的)を参照するかどうかを判断できません。


それはおそらくより少し知っているのですが、とにかく便利、あなたはメンバ関数に左辺値または右辺値REF-修飾子を置くことができます。ここでは、自然に暗黙のオブジェクトパラメータに右辺値参照の既存のセマンティクスを拡張する例です:今

struct string { 
    string& operator=(string const& other) & { /* ... */ } 
}; 

は、あなたはもう言うことができない混乱で、作りは本当にないです

string() = "hello"; 

ほとんどの時間を感じます。上記の&がしていることは、代入演算子は左辺値に対してのみ呼び出すことができるということです。右辺値については、&&とすることで同じことができます。

+1

+1 lvalues/rvalues onlyのメンバーコールについては、最後の部分はうれしくありがとう!私はC++ 0xについて多くのことを読んでいましたが、それについては何も見ませんでした(私はそれが最後のドラフトにあると思いますが、すべてを読まなかった)。この機能に関するいくつかのドキュメントを教えてください。 – Klaim

+0

ここでは素晴らしい概観です:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1821.htm。ワーキングペーパーでは、8.3.5,9.3.1、および13.3.1を参照してください。 –

+0

この回答をありがとう、これははるかに明確になります。私はちょうどrvalue参照を非常によく理解していませんでした。これは、私が思っていたよりもはるかに理にかなっています。 – Zifre

12

参照の新しい種類を追加すると、あなたは方法の2つのオーバーロードを書くことができますので:

void CopyFrom(MyClass &&c) 
{ 
    dataMember.swap(c); 
} 

void CopyFrom(const MyClass &c) 
{ 
    dataMember.copyTheHardWay(c); 
} 

参照の新しい種類を受け入れるバージョンは、それが受け取る変数を変更することが許可され、その変数ISN理由他の場所で使われることはありません。だから、それを "盗む"ことができます。

これがこの機能が追加された理由の1つです。 1つのタイプの参照を保持することは、所望の目標を達成しないであろう。

関連する問題