为什么string :: compare返回一个int?

为什么string::compare返回一个int而不是像shortchar这样的较小types? 我的理解是,这种方法只返回-1,0或1。

第二部分,如果我devise一个比较两个Footypes对象的比较方法,我只想返回-1,0或1,那么使用shortchar通常是个好主意?

编辑:我已被纠正, string::compare不会返回-1,0或1,它实际上返回一个值> 0,<0或0.谢谢让我排队。

似乎答案是粗略的,没有理由返回比int更小的types,因为返回值是“rvalues”,而那些“rvalues”不会比inttypes(4字节)小。 另外,很多人指出大多数系统的寄存器大小可能会变大,因为无论你给它们一个1,2或者4个字节的值,这些寄存器都将被填满,返回没有真正的好处一个较小的值。

编辑2:实际上,当使用较小的数据types(比如alignment,屏蔽等)时,看起来可能会有额外的处理开销。一般的共识是,处理大量数据时存在较小的数据types以节省内存,如一个数组的情况。

今天学了一些东西,再次感谢你们!

首先,规范是返回一个小于,等于或大于0 ,不一定是-11 。 其次,返回值是rvalues,受到整体提升的影响,所以返回更小的东西没有意义。

在C ++中(如在C中),每个expression式都是右值或左值。 从历史上看,这些术语指的是左值出现在赋值左边的情况,右值只能出现在右边。 今天,非类types的一个简单的近似值是左值在内存中有一个地址,右值不是。 因此,你不能取一个右值的地址,并且cv-qualifiers(条件是“access”)不适用。 用C ++来说,没有types的右值是一个纯粹的值,而不是一个对象。 函数的返回值是一个右值,除非它具有引用types。 (适合在寄存器中的非typestypes几乎总是被返回到寄存器中,例如,而不是在内存中)。

对于类types来说,由于可以在右值上调用成员函数,所以问题有点复杂。 这意味着右值必须实际上具有地址,对于this指针,并且可以是cv限定的,因为cv限定在重载parsing中起作用。 最后,C ++ 11引入了几个新的区别,以支持右值引用; 这些也主要适用于class级types。

积分式提升是指在expression式中使用小于int整数types作为右值时,在大多数情况下,它们将被提升为int 。 所以,即使我有一个variables声明short a, b; 在expression式a + bab在加法发生之前被提升为int 。 同样,如果我写a < 0 ,则比较是在a的值上完成a ,转换为int 。 在实践中,很less有这种情况发生,至less在2的补码机器中,整数算术包装(即除了极less数的外来物,今天 – 我认为Unisys大型机是唯一的例外)。 即使在更常见的机器上:

 short a = 1; std::cout << sizeof( a ) << std::endl; std::cout << sizeof( a + 0 ) << std::endl; 

应该给出不同的结果:第一个是相当于sizeof( short ) ,第二个sizeof( int ) (因为整数提升)。

这两个问题是正式正交的; 右值和左值与整体提升无关。 …积分促销只适用于右值,而大多数(但不是全部)您将使用右值的情况将导致整数升级。 出于这个原因,真的没有理由返回一个小于int的数值。 甚至有一个很好的理由不把它作为字符types返回。 像<<这样的重载操作符对于字符types的行为往往是不同的,所以你只想返回字符作为字符types。 (你可以比较一下:

 char f() { return 'a'; } std::cout << f() << std::endl; // displays "a" std::cout << f() + 0 << std::endl; // displays "97" on my machine 

不同之处在于,在第二种情况下,加法引起整体提升,导致<<被select的不同超载。

这是故意的,它不返回-1,0或1。

它允许(注意这不是用于string,但它同样适用于string)

 int compare(int *a, int *b) { return *a - *b; } 

这比以下的麻烦less很多:

 int compare(int *a, int *b) { if (*a == *b) return 0; if (*a > *b) return 1; return -1; } 

如果必须返回-1,0或1,那么这是你必须做的(或者沿着这些线)。

它也适用于更复杂的types:

 class Date { int year; int month; int day; } int compare(const Date &a, const Date &b) { if (a.year != b.year) return a.year - b.year; if (a.month != b.month) return a.month - b.month; return a.day - b.day; } 

在string的情况下,我们可以这样做:

 int compare(const std::string& a, const std::string& b) { int len = min(a.length(), b.length()); for(int i = 0; i < len; i++) { if (a[i] != b[i]) return a[i] - b[i]; } // We only get here if the string is equal all the way to one of them // ends. If the length isn't equal, "longest" wins. return a.length() - b.length(); } 

int 通常 (意味着在大多数现代硬件上)与系统总线和/或CPU寄存器相同大小的整数,即所谓的机器字。 因此int通常比较小的types传递的更快,因为它不需要alignment,屏蔽和其他操作。

较小的types主要用于为数组和结构提供RAM使用优化。 在大多数情况下,它们交换几个CPU周期(以alignment操作的forms)以获得更好的RAM使用。

除非你需要强制你的返回值是一个中等大小(char,short …)的有符号或无符号数字,否则你最好使用int,这就是为什么标准库会这样做。

这是一个C-ISM。

当C需要comparetypes函数时,它们总是返回一个int 。 C ++刚刚推出(不幸)。

但是,返回int实际上可能是最快的方法,因为它通常是正在使用的系统寄存器的大小。 (故意模糊)

该方法实际上并不返回集合{ -1, 0, 1 }的整数; 它实际上可以是任何整数值。

为什么? 我能想到的主要原因是int被认为是build筑的“自然尺寸”价值; 对这个尺寸的值的操作通常至less与对较小或较大值的操作一样快(并且在许多情况下更快)。 所以这是一个允许实现足够的松弛来使用最快的情况。

如果我要devise一个比较两个Footypes对象的比较方法,我只想返回-1,0或1,那么使用short或char通常是个好主意?

这将是好主意。 更好的方法是返回一个布尔(如果只想比较是否相等),或枚举(更多信息):

 enum class MyResult { EQUAL, LESS, GREATER }; MyResult AreEqual( const Foo &foo1, const Foo & foo2 ) { // calculate and return result } 

假设有些人正在将代码从C更改为C ++。 他们决定将strcmpreplace为string::compare

由于strcmp返回int ,所以string::compare返回int更容易。

可能使其工作更像strcmp这也有这套返回值 。 如果你想要移植代码,可能会更直观地让替代品尽可能靠近。

此外,返回值不仅是-11而且还有<0 0>0

另外,正如所提到的,由于回报受到整体提升的影响,因此将其缩小是没有意义的。

因为布尔返回值只能是两个可能的值(true,false),并且比较函数可以返回三个可能的值(小于,等于,大于)。

更新

虽然当然可以返回一个有符号的short,但如果你真的想实现自己的比较函数,你可以用两个布尔值来返回一个半字节或者结构值。