なぜ最初のものが参照を返すのですか?
int x = 1;
int y = 2;
(x > y ? x : y) = 100;
2番目はありませんか?
int x = 1;
long y = 2;
(x > y ? x : y) = 100;
実際、2番目はまったくコンパイルされませんでした-「割り当ての左辺値ではありません」。
なぜ最初のものが参照を返すのですか?
int x = 1;
int y = 2;
(x > y ? x : y) = 100;
2番目はありませんか?
int x = 1;
long y = 2;
(x > y ? x : y) = 100;
実際、2番目はまったくコンパイルされませんでした-「割り当ての左辺値ではありません」。
回答:
式には戻り値の型はなく、型と、最新のC ++標準で知られているように、値のカテゴリがあります。
条件式は左辺値または右辺値にすることができます。これがその価値カテゴリーです。(これは、C++11
左辺値、x値、およびprvalueがあるため、多少単純化されています。)
非常に広く単純な用語では、左辺値はメモリ内のオブジェクトを指し、右辺値はメモリ内のオブジェクトに必ずしも関連付けられていない場合がある値にすぎません。
割り当て式はオブジェクトに値を割り当てるため、割り当てられるものは左辺値でなければなりません。
条件式(?:
)を左辺値(ここでも、広義で単純な用語)にするには、2番目と3番目のオペランドが同じ型の左辺値でなければなりません。これは、条件式のタイプと値のカテゴリーがコンパイル時に決定され、条件が真かどうかに関係なく適切でなければならないためです。オペランドの一方が他方に合わせて異なる型に変換されなければならない場合、条件式であることができない左辺値ではないであろう、この変換の結果として左辺値。
ISO / IEC 14882:2011リファレンス:
3.10 [basic.lval]左辺値と右辺値(値カテゴリについて)
5.15 [expr.cond]条件演算子(条件式が持つ型と値のカテゴリの規則)
5.17 [expr.ass]代入演算子と複合代入演算子(代入のlhsは変更可能な左辺値でなければならないという要件)
an rvalue is just a value that may not necessarily be *attached* to an object in memory.
これをもっと簡単な言葉で説明できますか?。また、どういう意味type and value *category*
ですか?ありがとう
prvalue, xvalue, glvalue
値のカテゴリです。
true
、this
、enum
の値。これらはprvalues( "pure" rvalues)ですが、メモリには存在しません。
三項?:
式の型は、2番目と3番目の引数の共通型です。両方のタイプが同じ場合、参照が返されます。それらが相互に変換可能である場合、一方が選択され、もう一方が変換されます(この場合は昇格されます)。一時的な(変換/プロモートされた変数)への左辺値参照を返すことはできないため、その型は値型です。
の型と一致するように暗黙的にの型を昇格させる必要があるため(およびの両側が同じ型ではないため)、一時変数を作成する必要があるため、左辺値を返すことはできません。x
y
:
式5.17代入演算子と複合代入演算子
5.17 / 3
2番目と3番目のオペランドの型が異なり、どちらかが(おそらくcv修飾された)クラス型である場合、それらの各オペランドをもう一方の型に変換しようとします。タイプT1のオペランド式E1がタイプT2のオペランド式E2と一致するように変換できるかどうかを判別するプロセスは、次のように定義されます。
— E2が左辺値の場合:E1を暗黙的に変換でき(第4節)、「T2への参照」型に変換できる場合、変換で参照が直接バインドする必要があるという制約に従って、E1をE2に一致するように変換できます(8.5.3 )からE1へ。
— E2が右辺値の場合、または上記の変換を実行できない場合:
— E1とE2にクラスタイプがあり、基になるクラスタイプが同じであるか、一方が他方の基本クラスである場合:T2のクラスが同じタイプの基本クラスまたは、T1のクラス、およびT2のcv-qualificationは、T1のcv-qualificationと同じ、またはそれよりも大きいcv-qualificationです。変換が適用されると、E1は、元のソースクラスオブジェクト(またはその適切なサブオブジェクト)を引き続き参照するT2型の右辺値に変更されます。[ 注:つまり、コピーは作成されません。—エンドノート ]タイプT2の一時ファイルをE1からコピー初期化し、その一時ファイルを変換後のオペランドとして使用する。
それ以外の場合(つまり、
E1
またはE2に非クラスタイプがある場合、または両方にクラスタイプがあるが、基礎となるクラスが同じでも、一方が他方の基本クラスでもない場合):E1を変換できる場合、E1をE2に一致するように変換できます。 E2が右辺値に変換された場合に式E2が持つ型(またはE2が右辺値の場合はそれが持つ型)に暗黙的に変換されます。このプロセスを使用して、2番目のオペランドを3番目のオペランドと一致するように変換できるかどうか、および3番目のオペランドを2番目のオペランドと一致するように変換できるかどうかを決定します。両方を変換できる場合、または1つは変換できるが、変換があいまいな場合、プログラムの形式が正しくありません。どちらも変換できない場合、オペランドは変更されず、以下で説明するようにさらにチェックが行われます。正確に1つの変換が可能な場合、その変換は選択されたオペランドに適用され、このセクションの残りの部分では、変換されたオペランドが元のオペランドの代わりに使用されます。
5.17 / 4
2番目と3番目のオペランドが左辺値で同じ型の場合、結果はその型で左辺値であり、2番目または3番目のオペランドがビットフィールドの場合、または両方がビットフィールドの場合はビットフィールドです。田畑。
5.17 / 5
それ以外の場合、結果は右辺値です。2番目と3番目のオペランドが同じ型ではなく、どちらか(おそらくcv修飾)のクラス型である場合、過負荷解決を使用して、オペランドに適用される変換(存在する場合)を決定します(13.3.1.2、13.6) 。過負荷の解決に失敗した場合、プログラムは不正な形式です。それ以外の場合は、このように決定された変換が適用され、このセクションの残りの部分では、元のオペランドの代わりに変換されたオペランドが使用されます。