首先,规范指定返回值小于、等于或大于0
,不一定是-1
或1
。
其次,返回值是rvalues,需要整数提升,因此返回任何更小的值都没有意义。
在C++(以及C)中,每个表达式都是rvalue或lvalue。历史上,这些术语是指lvalues出现在赋值的左侧,而rvalues只能出现在右侧。今天,对于非类类型的简单近似是,lvalue具有内存中的地址,而rvalue则没有。因此,您不能获取rvalue的地址,并且cv限定符(用于“访问”)不适用。在C ++术语中,没有类类型的rvalue是一个纯值,而不是一个对象。函数的返回值是一个rvalue,除非它具有引用类型。(适合寄存器的非类类型通常会在寄存器中返回,例如,而不是在内存中返回。)
对于类类型,问题要复杂一些,这是由于您可以在rvalue上调用成员函数。这意味着rvalue实际上必须具有地址,用于
this
指针,并且可以是cv-qualified,因为cv限定符在重载分辨率中起作用。最后,C ++11引入了几个新的区分,以支持rvalue引用;这些也主要适用于类类型。
整数提升是指当比int小的整数类型在表达式中作为rvalue使用时,在大多数上下文中,它们将被提升为
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 )
(由于整数提升)。
这两个问题在形式上是正交的;rvalue和lvalue与整数提升无关。但是......
整数提升仅适用于rvalue,而大多数(但并非全部)使用rvalue的情况将导致
整数提升。因此,在返回比int
更小的数字值时真的没有理由。
甚至有一个非常好的理由不要将其作为字符类型返回。
像<<
这样的重载运算符通常对字符类型有不同的行为,
因此您只希望将字符作为字符类型返回。(您可以比较一下区别:
char f() { return 'a'; }
std::cout << f() << std::endl; // displays "a"
std::cout << f() + 0 << std::endl; // displays "97" on my machine
不同之处在于第二种情况中发生了整数提升,导致选择了不同的<<
重载。
string::compare()
文档明确说明它的返回值是<0, 0和>0,而不是-1,0和1。我会保持原意并使翻译更易懂。 - Captain Obvliousshort
或char
而不是int
的优点是什么?大多数计算机架构将函数的返回值存储在寄存器中,而一个int
同样适合于存储在寄存器中。并且当你需要确保有符号值被正确处理时,使用char
作为数字类型总是一个坏主意。 - Cody Graychar
会是个糟糕的选择,因为在char
被视为无符号数的平台上,检查返回值是否小于零的代码将失效。 - milleniumbug