左辺値はメモリの決定的な領域にバインドされた値ですが、右辺値は一時的な存在であり、必ずしもメモリの決定的な領域を参照するとは限らない式の値です。右辺値が予期される位置で左辺値が使用される場合は常に、コンパイラは左辺値から右辺値への変換を実行してから、評価を続行します。
http://www.eetimes.com/discussion/programming-pointers/4023341/Lvalues-and-Rvalues
一時的な (匿名の) クラス オブジェクトを構築するか、関数から一時的なクラス オブジェクトを返すときはいつでも、オブジェクトは一時的ですが、アドレス指定可能です。ただし、オブジェクトは依然として有効な右辺値です。これは、オブジェクトが a) アドレス指定可能な右辺値であるか、または b) コンパイラが左辺値の使用を想定しているときに、左辺値から右辺値に暗黙的に変換されていることを意味します。
例えば:
class A
{
public:
int x;
A(int a) { x = a; std::cout << "int conversion ctor\n"; }
A(A&) { std::cout << "lvalue copy ctor\n"; }
A(A&&) { std::cout << "rvalue copy ctor\n"; }
};
A ret_a(A a)
{
return a;
}
int main(void)
{
&A(5); // A(5) is an addressable object
A&& rvalue = A(5); // A(5) is also an rvalue
}
また、関数によって返される一時オブジェクト(次の場合) は、次のコード セグメントのように左辺値であることもわかっています。a
int main(void)
{
ret_a(A(5));
}
次の出力が得られます。
int conversion ctor
lvalue copy ctor
ret_a
実引数を使用した関数の呼び出しが、値 5 で関数の仮引数を構築A(5)
する変換コンストラクターを呼び出すことを示します。A::A(int)
a
関数の実行が完了すると、 を引数として使用して一時A
オブジェクトを作成し、 を呼び出します。ただし、オーバーロードされたコンストラクターのリストから削除した場合、返された一時オブジェクトは引き続き右辺値参照コンストラクターと一致します。a
A::A(A&)
A::A(A&)
A::A(A&&)
これは私がよく理解していないことです:オブジェクトa
が右辺値参照と左辺値参照の両方にどのように一致するのでしょうか? A::A(A&)
の方がより適切に一致することは明らかですA::A(A&&)
(したがってa
、左辺値である必要があります)。ただし、仮引数a
が左辺値である場合、右辺値参照は左辺値に初期化できないため、 への呼び出しと一致することはできませんA::A(A&&)
。コンパイラが左辺値から右辺値への変換を行っている場合、それは簡単です。'A' から 'A&' への変換も些細なことであり、両方の関数が同一の暗黙的な変換シーケンス ランクを持つ必要があるため、オーバーロードされた関数にA::A(A&)
との両方がある場合、コンパイラは最適な関数を推測できないはずです。A::A(A&&)
候補セット。
さらに、質問(以前に尋ねたもの)は次のとおりです。
特定のオブジェクトが右辺値参照と左辺値参照の両方に一致するにはどうすればよいですか?