问题
shared_ptr observers 20.8.2.2.5 C++14 Final Draft (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]
回答1:
According to this page
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.
with a reference to
John Lakos, Large-Scale C++ Software Design, section 9.2.2, page 637, Addison-Wesley, July 1996, ISBN 0-201-63362-0.
Basically, it looks like a nanny-grade decision, tailored for freshman year software developers.
回答2:
The reason is that the most appropriate type for a counter of this kind is a regular signed
integer, even if this counter is never going to get below 0.
Why a counter should be unsigned
? The fact that it cannot become negative is not a valid excuse at all given current real meaning of unsigned
for the language.
unsigned
for C++ doesn't mean an "integer number that cannot be negative". To understand why this definition simply doesn't make sense consider that
- The difference of two
unsigned
isunsigned
- The addition of an
unsigned
with asigned
isunsigned
- An
unsigned
value is never bigger than -1
None of the above makes any sense if you consider unsigned
to mean "non-negative".
Using unsigned
for size_t
was a mistake (see for example Why is size_t unsigned?), only partially* excusable because in the 16-bit era one extra bit was considered worth the wrong semantics that unsigned
types have in C++ for this kind of use.
Unfortunately now the size_t
mistake cannot be fixed (because of backward compatibility) but why repeating the same mistake in another unrelated area?
Please note that probably the big mistake made was just the choice of the name unsigned
(given its real meaning). If that type would have been named (more appropriately) modulo
then probably it would be more evident why using a modulo int
for the size of a string doesn't make any sense at all.
The name is irrelevant, what it counts is the semantic and unsigned
simply has the wrong semantic for a counter or a size.
(*) I personally don't think it was a good enough reason even back then. If 32767 is not enough for a size now, then 65535 won't be enough really soon. Just a single bit (twice the value) was not, in my opinion, an acceptable price for such a bending of the semantic.
EDIT
I've published a video in which I'm discussing in more details why I think that using and unsigned type for size_t
was a design mistake in C++.
Slides can be downloaded from http://raksy.dyndns.org/unsigned.pdf
来源:https://stackoverflow.com/questions/36370180/why-does-shared-ptrtuse-count-return-a-long-instead-of-an-unsigned-type