10

この質問rvalue、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 、 lvalue、 、xvalueglvalue、 、prvalue. 一番上の回答にはそれぞれの適切な説明があり、それらを読むとそれらの違いが理解できます. しかし、私はそれらを頭の中で整理するのに苦労しており、誰かがこれらの用語を使用するたびに、どれがどれであるかを思い出すためにグーグルで検索する必要があります.

一般的なニーモニックや、どれがどれであるかを人々が覚える他の方法はありますか? 現在のように、それらを混同することなく、すべてを頭の中でまっすぐに保ちたいと思っています。

4

3 に答える 3

9

私は2つの関連付けを行います:

  • 左辺値のアドレスのみを取得できます
  • xvalues はstd::move式とは何か

どちらでもない場合は、おそらく prvalue です。

ここで、glvalues と rvalues を思い出すために、次のグラフを想像してください。

lvalues と xvalues は両方とも glvalues ですが、xvalues と prvalues は両方とも rvalues です。実際に知っておくべきことはこれだけです。

おそらく、lvaluse、xvalues、および prvalues を覚えておくためのニーモニックは、単語Lower eXPRessions(L、X、および PR を含む) です。そうでないかもしれない。

于 2012-12-18T18:45:18.037 に答える
3

通常、何かが左辺値か右辺値かを知る必要があるだけです。これら 2 つの式のカテゴリは、互いに区別されます。

通常、左辺値式は、しばらくぶらぶらする何かを参照する場合です。たとえば、変数は固定されているため、変数名は左辺値です。一方、右辺値式は通常、一時的にしか存在しないものを参照します。左辺値のアドレスしか取得できません。なぜなら、すぐに消えてしまうもののアドレスが必要になるからです。

さて、この区別をするときは、コンパイラがその時点で知っていることを考慮に入れる必要があります。たとえば、関数を取り上げますvoid foo(const A& a)。この関数内では、コンパイラは渡されたオブジェクトが一時オブジェクトであるかどうかを認識していないため、そのまま残ると想定しています。つまりa、左辺値です。一時オブジェクトをこの関数に渡す (右辺値式で呼び出す) ことはできますが、式aは依然として左辺値です。

これを考慮に入れると、名前が付けられているかどうかによって、何かが左辺値か右辺値かをさらに思い出すことができます。上記の例では、オブジェクトは として名前が付けられるためa、左辺値です。

さて、残りのカテゴリについては、次の図を覚えておく必要があります。

式カテゴリの図

左辺値と右辺値は実際には異なることに注意してください。ただし、右辺値は、xvalues と prvalues という 2 つの別のカテゴリに分割されます。また、xvalue もすべての lvalue 式と共に glvalue と見なされます。

これらがいつ現れるかを知ることは、いくつかのケースを思い出すことに帰着します。

xvaluesはあまり一般的ではありません。これらは、右辺値参照への変換を伴う状況でのみ表示されます。すべてのケースは次のとおりです。

  • 右辺値参照を返す関数の結果
  • 右辺値参照へのキャスト
  • object.xobjectxvalue の場合
  • object.*memberpobjectxvalue の場合

定義上、prvaluesは、xvalue ではない他のすべてのタイプの右辺値です。たとえば、関数から値によってオブジェクトを返すと、一時的に返されるオブジェクトが作成されます。オブジェクトが prvalue であることを示す式。

カテゴリglvalueは、prvalue ではないすべてのものを参照するために使用されます。

于 2012-12-18T18:53:57.623 に答える
0

左辺値は、「名前付き」変数またはメモリ位置と考えることができます...右辺値は、「名前のない」メモリ位置 (つまり、関数から返される一時変数) または純粋な「値」 (つまり、 、数字のように)。

于 2012-12-18T18:41:51.490 に答える