前提:
C++11 標準は、式を 3 つの互いに素な値のカテゴリ: lvalues、xvalues、およびprvalues (§ 3.10/1) に分類します。値カテゴリの説明は、たとえばここにあります。
オペランドの値カテゴリに関するさまざまな演算子の要件を理解するのに苦労しています。パラグラフ 3.10/1 は次のように規定しています。
[...] すべての式は、この分類法の基本的な分類の 1 つに正確に属します: lvalue、xvalue、または prvalue。式のこのプロパティは、その値カテゴリと呼ばれます。[ 注: 第5 節の各組み込み演算子の説明は、それが生成する値のカテゴリと、期待されるオペランドの値のカテゴリを示しています。たとえば、組み込み代入演算子は、左側のオペランドが左辺値であり、右側のオペランドが prvalue であると想定し、結果として左辺値を生成します。ユーザー定義演算子は関数であり、期待値と生成値のカテゴリは、パラメーターと戻り値の型によって決まります。—終わりのメモ]
上記の注記が主張していることにもかかわらず、節 5 は、演算子のオペランドの値のカテゴリについて常に明確であるとは限りません。たとえば、これは、代入演算子のオペランドの値カテゴリについて述べられているすべてです (パラグラフ 5.17/1)。
代入演算子 (=) と複合代入演算子はすべて右から左にグループ化されます。すべてが左オペランドとして変更可能な左辺値を必要とし、左オペランドを参照する左辺値を返します。左オペランドがビットフィールドの場合、結果は常にビットフィールドになります。いずれの場合も、代入は、右オペランドと左オペランドの値の計算の後、代入式の値の計算の前に順序付けされます。不定順序の関数呼び出しに関しては、複合代入の操作は単一の評価です。[ 注: したがって、関数呼び出しは、左辺値から右辺値への変換と、単一の複合代入演算子に関連する副作用との間に介在してはなりません。—終わりのメモ]
正しいオペランドはどうですか?
「右辺値」と「左辺値」という単語は、セクション 5.17 全体で使用されなくなりました。段落 3.10/1 の注記では、組み込みの代入演算子が右オペランドとして prvalue を期待することが明示されていますが、これはセクション 5.17 では明示的に言及されていません。左辺値から右辺値への変換について言及している 5.17/1 の最後の注記でさえ、何らかの形で右辺値が期待されていることを暗示しているように見えます (それ以外の変換の必要性は何ですか?)。
乗法および加法演算子を含む他の演算子に関するセクションでは、通常、オペランドの値のカテゴリについては言及されていません。特に指定されていない場合、組み込み演算子のオペランドは右辺値であると述べている「デフォルトステートメント」が標準に見つかりませんでした。したがって、質問です。
質問:
- 代入演算子の右オペランドの値カテゴリは何ですか; そして、より一般的に
- これが指定されていない場合、演算子のオペランドの値カテゴリを把握する方法は? 制約はありませんか (任意の値カテゴリが受け入れられることを意味します)? もしそうなら、なぜ左辺値から右辺値への変換が代入式に適用されるべきなのでしょうか?
C++11 標準への参照は高く評価されます。