Почему std::count_if возвращает значение со знаком, а не без знака?

Только что понял, что std::count_if возвращает значение со знаком.

Почему он разработан таким образом? Это не имеет смысла (результатом может быть только натуральное число, то есть неотрицательное целое число), на мой взгляд, так как это не позволяет сделать что-то настолько простое, как сравнение этого результата с size() контейнера без получения предупреждения или использования явного преобразование типов.

Я действительно думаю, что возвращаемый тип должен иметь size_type.

Я что-то упускаю?


person Violet Giraffe    schedule 10.03.2015    source источник
comment
Имеет смысл возвращать difference_type итератора для count, так как это в значительной степени просто разница аргументов, имеет смысл сохранить этот интерфейс для count_if, и в равной степени имеет смысл для difference_type быть подписанным для двунаправленного итераторы.   -  person BoBTFish    schedule 10.03.2015
comment
Точно так же, почему нельзя разделить два std::list за постоянное время?   -  person W.F.    schedule 10.03.2015
comment
@WojciechFrohmberg: Просто, вам нужно посчитать элементы. Однажды созданный список имеет O (1) .size(), что означает, что он кэширован,   -  person MSalters    schedule 10.03.2015
comment
@MSalters Но вы можете сохранить позицию в итераторе, который можно использовать для разделения списка, потому что он может быть амортизирован ...   -  person W.F.    schedule 10.03.2015
comment
@WojciechFrohmberg: Как бы вы сохранили эту позицию в актуальном состоянии? Помните, что вы можете вызывать push_front в списке, не делая недействительными существующие итераторы, и, очевидно, это изменяет положение всех существующих итераторов на единицу.   -  person MSalters    schedule 10.03.2015
comment
@MSalters: да, я понимаю вашу точку зрения ... Спасибо за разъяснение.   -  person W.F.    schedule 10.03.2015


Ответы (1)


Я думаю, что тип возвращаемого значения должен быть совместим с std::count, который принимает два итератора (подумайте об указателях) и возвращает промежуточные значения (которые вы можете рассматривать как разницу двух указателей). Разница указателей (как используется в ptrdiff_t) должна быть значением со знаком.

Благодаря совместимости с std::count вы можете легко сравнить результаты этих двух функций.

Изменить: здесь нет недостатка, связанного с диапазоном, при использовании значения со знаком, поскольку значение будет по крайней мере находиться в диапазоне [0, std::count], который сам будет находиться в диапазоне [0, end_ptr - start_ptr]. Поскольку end_ptr - start_ptr набирается как ptrdiff_t или подобное, оно подписано.

person urzeit    schedule 10.03.2015
comment
Бред какой то. Описание std::count ясно говорит: Возвращает количество элементов в диапазоне [first,last), которые при сравнении равны val. Количество элементов не может быть отрицательным. Тип count аргументов (итераторов) совершенно не связан. - person Violet Giraffe; 10.03.2015
comment
@VioletGiraffe: Да. Количество элементов не может быть отрицательным. Но сигнатуры count и count_if содержат итераторы. Я не говорил, что имеет смысл определять количество подписанных элементов... - person urzeit; 10.03.2015