为什么 shared_ptr<T>::use_count() return 是 long 而不是无符号类型?

Why does shared_ptr<T>::use_count() return a long instead of an unsigned type?

shared_ptr 观察者 20.8.2.2.5 C++14 最终草案 (n4296)

   long use_count() const noexcept;

Returns: the number of shared_ptr objects, *this included, that share ownership with *this, or 0 when *this is empty.

[Note: use_count() is not necessarily efficient. — end note]

原因是这种计数器最合适的类型是常规 signed 整数,即使此计数器永远不会低于 0。

为什么计数器应该是 unsigned?考虑到该语言当前 unsigned 真正意义 ,它不能变成负数这一事实根本不是一个有效的借口。

unsigned 对于 C++ 并不意味着 "integer number that cannot be negative"。要理解为什么这个定义根本没有意义,请考虑

  • 两个unsigned的差是unsigned
  • 一个unsigned加上一个signed就是unsigned
  • unsigned 值永远不会大于 -1
如果您认为 unsigned 表示 "non-negative".

,则上述

None 有意义

unsigned 用于 size_t 是一个错误(参见示例 Why is size_t unsigned?),只有部分*是可以原谅的,因为在 16 位时代,一个额外的位被认为是错误的unsigned 类型在 C++ 中用于此类用途的语义。

不幸的是,size_t 错误现在无法修复(因为向后兼容),但为什么在另一个不相关的领域重复同样的错误?

请注意,可能犯的最大错误只是名称的选择 unsigned(考虑到它的真实含义)。如果该类型被命名为(更恰当地)modulo 那么可能会更清楚为什么使用 modulo int 作为字符串的大小根本没有任何意义。

名称无关紧要,重要的是语义,unsigned 只是计数器或大小的语义错误。

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

编辑

我发布了一篇 video,其中我更详细地讨论了为什么我认为 size_t 使用和无符号类型是 C++ 中的设计错误。

可以从 http://raksy.dyndns.org/unsigned.pdf

下载幻灯片

根据此页面

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1450.html

The return type of use_count is signed to avoid pitfalls such as p.use_count() > -1 evaluating to false.

参考

John Lakos, Large-Scale C++ Software Design, section 9.2.2, page 637, Addison-Wesley, July 1996, ISBN 0-201-63362-0.

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