string::size_type вместо int

const std::string::size_type cols = greeting.size() + pad * 2 + 2;

Почему string::size_type? int должно работать! он хранит числа!!!


person Delirium tremens    schedule 25.07.2009    source источник


Ответы (3)


Шорт также содержит числа. Как и подписанный char.

Но ни один из этих типов не может быть достаточно большим, чтобы представлять размеры любых строк.

string::size_type гарантирует именно это. Это тип, который достаточно велик, чтобы представить размер строки, независимо от того, насколько велика эта строка.

В качестве простого примера того, почему это необходимо, рассмотрим 64-битные платформы. Int обычно все еще 32-битный, но у вас гораздо больше, чем 2 ^ 32 байта памяти.

Поэтому, если использовалось (подписанное) целое число, вы не смогли бы создать строки, длина которых превышает 2 ^ 31 символ. Однако size_type будет 64-битным значением на этих платформах, поэтому он может без проблем представлять большие строки.

person jalf    schedule 25.07.2009
comment
Это также относится к PowerPC и Cell. И, насколько я помню, на Альфе тоже. Плюс, конечно, я думаю, что x64 — это типичный 64-битный процессор в наши дни. ;) Но вы правы, это явно зависит от платформы. - person jalf; 25.07.2009
comment
О какой 64-битной платформе Linux мы говорим? На машинах x64 в последний раз, когда я пробовал, все еще были 32-битные целые числа. А на процессорах Cell int тоже 32 бита. Кроме того, я предполагаю, что то же самое относится и к Linux на PowerPC. Так что нет, Linux ABI варьируется от платформы к платформе, и большинство известных мне платформ задают 4-битные целые числа, даже в Linux. - person jalf; 27.07.2009
comment
Но ты прав. Аппаратное обеспечение обычно определяет общий ABI, которому программное обеспечение должно следовать, чтобы обеспечить совместимость. ОС определяет ABI, который обычно идентичен, но может и не совпадать. И компилятор на самом деле реализует ABI, который снова обычно следует за ОС, но, строго говоря, не обязан. - person jalf; 27.07.2009
comment
А также за независимость от машин. - person psrag anvesh; 09.03.2016

Пример, который вы привели,

const std::string::size_type cols = greeting.size() + pad * 2 + 2;

взят из Accelerated C++ by Koenig. Сразу после этого он также называет причину своего выбора, а именно:

Тип std::string определяет size_type как имя соответствующего типа для хранения количества символов в строке. Всякий раз, когда нам нужно, чтобы локальная переменная содержала размер строки, мы должны использовать std::string::size_type в качестве типа этой переменной.

Причина, по которой мы присвоили cols тип std::string::size_type, состоит в том, чтобы гарантировать, что cols способен содержать количество символов приветствия, независимо от того, насколько большим может быть это число. Мы могли бы просто сказать, что cols имеет тип int, и действительно, это сработало бы. Однако значение cols зависит от размера входных данных для нашей программы, и мы не можем контролировать, насколько длинными могут быть эти входные данные. Вполне возможно, что кто-то может дать нашей программе строку такой длины, что int будет недостаточно для ее длины.

person mihai    schedule 21.10.2013

Вложенный size_type typedef является обязательным требованием для STL-совместимых контейнеров (каким оказывается std::string), поэтому универсальный код может выбрать правильный целочисленный тип для представления размеров.

Нет смысла использовать его в коде приложения, size_t вполне нормально (int нет, потому что он подписан, и вы получите предупреждения о сравнении подписанных/неподписанных).

person Marc Mutz - mmutz    schedule 25.07.2009
comment
Можно ли зайти так далеко, чтобы сказать, что нет смысла? Возможно, если вам не нужен наиболее переносимый код, можно было бы использовать size_t. Или для большинства практических ситуаций сегодня вы можете обойтись size_t. Но если бы в этом не было смысла, size_type не существовало бы, не так ли? - person Steven Lu; 03.07.2013
comment
size_t является гарантированно достаточно большим, поэтому в лучшем случае вы тратите немного места (в регистре или в стеке) на использование значения, превышающего необходимое. Эти определения типов предназначены для использования в универсальном коде, а не при использовании std::string, который является конкретной моделью. То есть, если вы находитесь в функции шаблона, принимающей произвольное basic_string, особенно. с произвольным распределителем следует использовать вложенный typedef. Но да, в std::string нет смысла, потому что size_t вполне нормально. - person Marc Mutz - mmutz; 09.02.2015
comment
size_t не подписан. Пока вы сравниваете с std::string::npos (в отличие от pos >= 0), все должно быть в порядке. - person Jason; 08.09.2017