Почему shared_ptr <T>:: use_count() возвращает длинный вместо неподписанного типа?
shared_ptr наблюдатели 20.8.2.2.5 С++ 14 Final Draft (n4296)
long use_count() const noexcept;
Возвращает: количество shared_ptr
объектов, *this
включено, которые разделяют право собственности на *this
или 0, когда *this
пуст.
[Примечание: use_count()
не обязательно эффективен. - конечная нота]
Ответы
Ответ 1
В соответствии с этой страницей
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1450.html
Возвращаемый тип use_count подписан, чтобы избежать ошибок, таких как p.use_count() > -1, оценивая значение false.
со ссылкой на
Джон Лакос, крупномасштабная разработка программного обеспечения на C++, раздел 9.2.2, стр. 637, Addison-Wesley, июль 1996 года, ISBN 0-201-63362-0.
В принципе, это похоже на решение для няни, предназначенное для разработчиков программного обеспечения, созданных в течение первого года.
Ответ 2
Причина в том, что наиболее подходящим типом для такого счетчика является регулярное целое число signed
, даже если этот счетчик никогда не будет ниже 0.
Почему счетчик должен быть unsigned
? Тот факт, что он не может стать отрицательным, не является действительным оправданием при данном текущем реальном значении unsigned
для языка.
unsigned
для С++ не означает "целое число, которое не может быть отрицательным". Чтобы понять, почему это определение просто не имеет смысла, считаем, что
- Разница двух
unsigned
составляет unsigned
- Добавление
unsigned
с signed
равно unsigned
- Значение
unsigned
никогда не больше -1
Ничто из перечисленного не имеет никакого смысла, если вы считаете, что unsigned
означает "неотрицательный".
Использование unsigned
для size_t
было ошибкой (см., например, Почему size_t unsigned?), только частично * простительно, потому что в 16-разрядную эру один дополнительный бит считался достойным неправильной семантики, которую unsigned
имеют типы в С++ для такого использования.
К сожалению, теперь ошибка size_t
не может быть исправлена (из-за обратной совместимости), но зачем повторять ту же ошибку в другой не связанной области?
Обратите внимание, что, вероятно, большая ошибка была просто выбором названия unsigned
(учитывая его реальный смысл). Если бы этот тип был бы назван (более подходящим образом) modulo
, то, вероятно, было бы более очевидно, почему использование modulo int
для размера строки не имеет никакого смысла.
Имя не имеет значения, то, что он считает семантикой, и unsigned
просто имеет неправильную семантику для счетчика или размера.
(*) Я лично не думаю, что это была хорошая причина даже тогда. Если 32767 недостаточно для размера сейчас, то 65535 не будет достаточно скоро. Только один бит (в два раза больше) не был, на мой взгляд, приемлемой ценой для такого изгиба семантики.
ИЗМЕНИТЬ
Я опубликовал видео, в котором я более подробно расскажу, почему я думаю, что использование и неподписанный тип для size_t
была ошибкой дизайна в С++.
Слайды можно загрузить из http://raksy.dyndns.org/unsigned.pdf