首先,规范是它将返回一个小于、等于或大于的值0
,不一定是-1
或1
。其次,返回值是右值,受积分提升的影响,因此返回更小的值是没有意义的。
在 C++ 中(就像在 C 中一样),每个表达式都是右值或左值。从历史上看,这些术语指的是左值出现在赋值的左侧,而右值只能出现在右侧。今天,非类类型的一个简单近似是左值在内存中有一个地址,而右值没有。因此,您不能获取右值的地址,并且 cv 限定符(条件“访问”)不适用。在 C++ 术语中,没有类类型的右值是纯值,而不是对象。函数的返回值是一个右值,除非它具有引用类型。(例如,适合寄存器的非类类型几乎总是在寄存器中返回,而不是在内存中。)
对于类类型,问题有点复杂,因为您可以在右值上调用成员函数。这意味着右值实际上必须具有this
指针的地址,并且可以是 cv 限定的,因为 cv 限定在重载解析中起作用。最后,C++11 引入了几个新的区别,以支持右值引用;这些也主要适用于类类型。
整数提升是指当小于 an 的整数类型int
在表达式中用作右值时,在大多数情况下,它们将被提升为int
。因此,即使我short a, b;
在表达式中声明了一个变量,在加法发生之前a
+ b
,两者a
和都会b
被提升。int
同样,如果我写a < 0
,则对 的值进行比较a
,转换为int
。在实践中,很少有这种情况会产生影响,至少在整数算术换行的 2 的补码机器上(即,今天除了极少数外来的机器之外——我认为 Unisys 大型机是唯一的例外)。尽管如此,即使在更常见的机器上:
short a = 1;
std::cout << sizeof( a ) << std::endl;
std::cout << sizeof( a + 0 ) << std::endl;
应该给出不同的结果:第一个等效于
sizeof( short )
,第二个sizeof( int )
(因为积分提升)。
这两个问题在形式上是正交的;右值和左值与积分提升无关。 除了...积分提升仅适用于右值,并且大多数(但不是全部)使用右值的情况将导致积分提升。因此,实际上没有理由返回小于 的数值int
。甚至有一个很好的理由不将其作为字符类型返回。重载的运算符,如<<
,对于字符类型通常表现不同,因此您只想将字符作为字符类型返回。(您可以比较差异:
char f() { return 'a'; }
std::cout << f() << std::endl; // displays "a"
std::cout << f() + 0 << std::endl; // displays "97" on my machine
不同的是,在第二种情况下,加法导致发生积分提升,从而导致<<
选择不同的重载。