C++ 为什么共享_ptr<;T>;::是否使用_count()返回长类型而不是无符号类型?

C++ 为什么共享_ptr<;T>;::是否使用_count()返回长类型而不是无符号类型?,c++,c++14,shared-ptr,C++,C++14,Shared Ptr,共享ptr观察员20.8.2.2.5 C++14最终草案(n4296) 返回:与*this共享所有权的共享\u ptr对象(包括*this)的数量,或者当*this为空时返回0 [注意:use\u count()不一定有效。-结束注意] 原因是,对于此类计数器,最合适的类型是正则的有符号的整数,即使此计数器永远不会低于0 为什么计数器应该是无符号的?鉴于该语言当前的无符号的的真正含义,它不能成为否定的事实根本不是一个有效的借口 < C++ >代码>未签名< /C> >并不意味着“整数不能否定”。

共享ptr观察员20.8.2.2.5 C++14最终草案(n4296)

返回:与
*this
共享所有权的
共享\u ptr
对象(包括
*this
)的数量,或者当
*this
为空时返回0

[注意:
use\u count()
不一定有效。-结束注意]


原因是,对于此类计数器,最合适的类型是正则的
有符号的
整数,即使此计数器永远不会低于0

为什么计数器应该是无符号的?鉴于该语言当前的
无符号的
的真正含义,它不能成为否定的事实根本不是一个有效的借口

< C++ >代码>未签名< /C> >并不意味着“整数不能否定”。要理解为什么这个定义根本没有意义,考虑到

  • 两个
    unsigned
    的差异是
    unsigned
  • 无符号
    有符号
    相加就是
    无符号
  • 无符号
    值永远不会大于-1

上述任何一点都没有意义,如果您考虑<代码>未签名< /C> >表示“非负”。

使用<代码>未签名< /C> > <代码> > SIEZHET是错误的(例如,),部分是可原谅的,因为在16位的时代,一个额外的位被认为是错误的语义,即“代码>未签名的< /代码>类型在C++中有这种用途。 不幸的是,现在无法修复

size\u t
错误(因为向后兼容),但是为什么要在另一个不相关的区域重复相同的错误呢

请注意,所犯的最大错误可能只是选择了名称
unsigned
(考虑到它的真正含义)。如果将该类型命名为(更合适的)
modulo
,那么可能更明显的是,为什么对字符串的大小使用
modulo int
毫无意义

名称是不相关的,它计算的是语义,
unsigned
只是计数器或大小的语义错误

(*)我个人认为即使在当时,这也不是一个足够好的理由。如果32767现在还不够一个尺码,那么65535很快就不够了。在我看来,仅仅一个比特(值的两倍)对于这种语义扭曲来说是不可接受的价格

编辑

我已经发表了一个更详细的讨论,为什么我认为使用C++和无符号类型的代码> SiZeStIt <代码>是C++中的一个设计错误。 幻灯片可根据本页从

下载

use\u count的返回类型是经过签名的,以避免诸如 p、 使用_count()>-1计算为false

关于

< P > John Lakos,大型C++软件设计,第637版,第2页,Addison Wesley,1996年7月,ISBN 0201-63362-0.


基本上,这看起来像是一个保姆级别的决定,专为一年级的软件开发人员量身定做。

这是一个咆哮,而不是答案。你的主张需要有理由来解释,并为读者提供任何好处。@6502:首先,斯特劳斯特鲁普有权发表自己的意见,但他错了。第二,无论有什么选择,早就作出了决定。标准库大小/计数未签名。究竟为什么这一个突然签署确实是不清楚的。使用无符号类型的计数/大小与获得值范围的额外位无关。@ 6502:第三,无符号类型的性质与主导C和C++迭代器语义的开放封闭范围的性质一致。它一直存在于语言的核心,是无法避免的。这不是一个人的决定,而是世界如何运转。因此,最初的错误实际上是推进签名类型——甚至在Stroustrup之前就犯了这个错误。签名类型属于特定于应用程序的域。编程本身是无符号的、无符号的和无符号的,而且很少有符号。@janm:在很多情况下,单个数组(单个字节)需要占用超过一半的地址空间。甚至更少的情况下,您无法为该大小使用多精度整数(例如,
long
)。使用这些用例来改变所有其他用例的规则,因为我认为这是一个值得怀疑的选择而谴责未来几代程序员犯下愚蠢的错误。当然,如果非负整数有另一个整数类型(具有正确的语义),那就太好了。。。但是
unsigned
并不是这样。在经历了十多年的编程经验之后,我不使用
unsigned
类型进行数学/逻辑运算,例如比较。我仅在按位操作的情况下使用
无符号
。例如,由于从有符号到无符号的自动转换,导致
-1
成为一个非常大的值,因此它使我免于许多陷阱。我想知道,如果计数超过
LONG_MAX
,那么定义的行为是什么?我猜到那时,软件在其他方面已经筋疲力尽了。。。看起来像我的第三颗子弹。一个简单易用的界面,不管他们在想什么。LakOS书是优秀的,可能是影响我的C++的书。一个规则是接口中没有未签名的类型。这不是一个“保姆级别的决定,为大一软件开发人员量身定做的”,而是关于如何扩展软件开发和保持软件可靠性的深刻建议。请注意,在本答案中给出的引用之后,还声明了以下内容:“use\u count的long返回类型并不意味着实现应该始终使用long作为引用计数。在某些情况下,对于下面使用的实际类型,size_t或其签名的等价物可能是更好的候选者。”对于此返回类型,这是一个错误的选择
   long use_count() const noexcept;