0
まず、仕様では、必ずしも-1
またはではなく、より小さい、等しい、またはより大きい値を返します1
。第二に、戻り値は汎整数拡張の対象となる右辺値であるため、小さいものを返す意味はありません。
C ++(Cの場合と同様)では、すべての式は右辺値または左辺値のいずれかです。歴史的に、これらの用語は、左辺値が割り当ての左側に表示されるのに対し、右辺値は右側にのみ表示されるという事実を指します。今日、非クラス型の簡単な概算は、左辺値がメモリ内にアドレスを持っているが、右辺値は持っていないということです。したがって、右辺値のアドレスを取得することはできず、cv-qualifiers(「アクセス」を条件とする)は適用されません。C ++の用語では、クラス型を持たない右辺値は純粋な値であり、オブジェクトではありません。関数の戻り値は、参照型でない限り、右辺値です。(レジスターに収まる非クラス型は、ほとんどの場合、たとえば、メモリーではなくレジスターで返されます。)
クラス型の場合、右辺値でメンバー関数を呼び出すことができるため、問題はもう少し複雑です。つまり、右辺値には実際にはthis
ポインターのアドレスが必要であり、cv修飾は過負荷の解決に役割を果たすため、cv修飾を行うことができます。最後に、C ++ 11では、右辺値参照をサポートするために、いくつかの新しい区別が導入されています。これらも、主にクラスタイプに適用できます。
汎整数拡張とは、aより小さい整数型int
が式の右辺値として使用される場合、ほとんどのコンテキストで、それらがに昇格されるという事実を指しint
ます。したがってshort a, b;
、式で変数が宣言されている場合でも、とはa
+ b
両方とも、加算が行われる前にプロモートされます。同様に、と書くと、の値で比較が行われ、に変換されます。実際には、これが違いを生むケースはほとんどありません。少なくとも、整数演算がラップする2の補数マシンでは(つまり、今日、非常に少数のエキゾチックなものを除いて、Unisysメインフレームだけが残っている例外だと思います)。それでも、より一般的なマシンでも:a
b
int
a < 0
a
int
short a = 1;
std::cout << sizeof( a ) << std::endl;
std::cout << sizeof( a + 0 ) << std::endl;
sizeof( short )
異なる結果が得られるはずです。最初の結果は、2番目の結果と同等です
sizeof( int )
(汎整数拡張のため)。
これらの2つの問題は形式的に直交しています。右辺値と左辺値は、汎整数拡張とは何の関係もありません。 ただし、...整数拡張は右辺値にのみ適用され、右辺値を使用する場合のほとんど(すべてではない)が整数拡張になります。このため、。よりも小さい数値を返す理由は実際にはありませんint
。文字タイプとして返さないのには非常に理由があります。のようなオーバーロードされた演算子は<<
、多くの場合、文字タイプに対して異なる動作をするため、文字を文字タイプとして返すだけです。(違いを比較するかもしれません:
char f() { return 'a'; }
std::cout << f() << std::endl; // displays "a"
std::cout << f() + 0 << std::endl; // displays "97" on my machine
違いは、2番目のケースでは、加算によって汎整数拡張が発生し、その結果、<<
選択されるの異なる過負荷が発生することです。