Как может size_type быть целым числом без знака, если npos равно -1?

Если std::size_type из std::string соответствует распределителю по умолчанию,

21.3.1 Шаблон класса basic_string
typedef typename allocator_traits<Allocator>::size_type size_type;

А std::size_type для распределителя по умолчанию — это std::size_t,

20.9.9 Распределитель по умолчанию
typedef size_t size_type;

И мы знаем, что std::size_t всегда является целым числом без знака,

Стандарт C++
5.3.3 Sizeof
Результатом sizeof и sizeof... является константа типа std::size_t.
[Примечание: std: :size_t определяется в стандартном заголовке <cstddef>

8.2 Типы
Содержимое совпадает с заголовком <stddef.h> стандартной библиотеки C со следующими изменениями:


Стандарт C
6.5.3.4 Операторы sizeof и _Alignof
Значение результата обоих операторов определяется реализацией,
и его типом ( целочисленный тип без знака) — это size_t, определенный в <stddef.h> (и других заголовках).

Как std::basic_string::npos (определяется как size_type) быть -1?


person Trevor Hickey    schedule 02.05.2016    source источник
comment
Это -1 неявно преобразуется в size_type?   -  person T.C.    schedule 02.05.2016
comment
Вы действительно читали страницу, на которую ссылаетесь? Там в первом предложении говорится: Это специальное значение, равное максимальному значению, которое может быть представлено типом size_type.   -  person 463035818_is_not_a_number    schedule 02.05.2016


Ответы (2)


Спецификация C++ требует, чтобы типы со знаком могли быть преобразованы в типы без знака. 4.7/2 говорится, что

Если целевой тип беззнаковый, результирующее значение является наименьшим целым числом без знака, соответствующим исходному целому числу (по модулю 2n, где n — количество битов, используемых для представления беззнакового типа).

Это означает, что спецификация C++ гарантирует, что -1 может быть преобразовано в size_type, даже если size_type не имеет знака, и результат будет равен максимально возможному size_type, потому что добавление 1 к этому числу должно вернуть 0.

person templatetypedef    schedule 02.05.2016
comment
Другими словами, если бы это было 2 байта, это было бы 0xFFFF. - person DarthRubik; 02.05.2016

В определении используется тот факт, что целые числа без знака следуют модульной арифметике, и -1 преобразуется в наибольшее целое число без знака данного типа.

person juanchopanza    schedule 02.05.2016
comment
Хорошо, есть смысл. Я не думал, что можно конструировать беззнаковые интегралы с отрицательными числами и полагаться на такой алгоритм потери значимости. - person Trevor Hickey; 02.05.2016