それは無意味です。関数内のものを変更すると、実際には一時的なものであるため、変更はすぐに失われます。
新しい型の理由は、実際に何が右辺値で、何が右辺値でないかを決定できるようにする必要性から生じています。そうして初めて、それらが使用されているクールなものに実際に使用できます。
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));
}
ここで、右辺値を持っていてそれを toupper に渡すと、一時的なものは使い捨てであることがわかっているため、右辺値を直接変更できます。したがって、変更するだけでコピーする必要はありません。また、move-constructors と move-assignment と呼ばれるものにも同じ観察が使用されます。右側はコピーされていませんが、その内容が盗まれて に移動されてい*this
ます。
右辺値が const 以外の左辺値参照にバインドできると言う場合、それが最終的に左辺値 (名前付きオブジェクト) を参照するのか右辺値 (一時的) を参照するのかを判断する方法はありません。
おそらくあまり知られていませんが、とにかく便利です。メンバー関数に左辺値または右辺値の参照修飾子を配置できます。次の例では、右辺値参照の既存のセマンティクスを暗黙のオブジェクト パラメータに自然に拡張しています。
struct string {
string& operator=(string const& other) & { /* ... */ }
};
今、あなたはもう言うことができません
string() = "hello";
これは紛らわしく、ほとんどの場合、実際には意味がありません。上記は、&
代入演算子は左辺値でのみ呼び出すことができると言っています。を配置することにより、右辺値についても同じことができます&&
。