Типы векторных типов С++
Я только начал изучать C++ и задал вопрос о векторах. В книге, которую я читаю, говорится, что если я хочу извлечь размер вектора типа double (например), я должен сделать что-то вроде:
vector<double>::size_type vector_size;
vector_size = myVector.size();
Если в Java я мог бы сделать
int vector_size;
vector_size = myVector.size();
Мой вопрос: почему существует тип vector :: size_type? Почему C++ просто не использует int?
Ответы
Ответ 1
C++ - это язык для написания библиотек *, позволяющий автору быть как можно более общим, является одной из его ключевых сильных сторон. Вместо того, чтобы предписывать стандартные контейнеры использовать какой-либо конкретный тип данных, более общий подход заключается в том, чтобы size_type
что каждый контейнер выставляет size_type
элемента size_type
. Это обеспечивает большую гибкость и универсальность. Например, рассмотрим этот общий код:
template <template <typename...> Container, typename T>
void doStuff(const Container<T> & c)
{
typename Container<T>::size_type n = c.size();
// ...
}
Этот код будет работать над любым шаблоном контейнера (который может быть создан с помощью одного аргумента), и мы не накладываем никаких лишних ограничений на пользователя нашего кода.
(На практике большинство типов размеров будут решаться на std::size_t
, который, в свою очередь, является неподписанным типом, обычно unsigned int
или unsigned long
- но почему мы должны это знать?)
*) Я не уверен, что будет для Java.
Ответ 2
Java не имеет неподписанных целых типов, поэтому они должны идти с int
.
Напротив, C++ делает и использует их там, где это необходимо (где отрицательные значения бессмысленны), канонический пример - длина чего-то типа массива.
Ответ 3
В стандарте C++ указано, что контейнер size_type
является неподписанным интегральным типом, но он не указывает, какой из них; одна реализация может использовать unsigned int
а другая может использовать unsigned long
, например.
C++ не "защищен" от деталей реализации конкретной платформы, как Java. size_type
помогает защитить ваш код от таких деталей, поэтому он будет работать правильно, независимо от того, какой фактический тип должен использоваться для представления векторного размера.
Ответ 4
Мое личное мнение об этом заключается в том, что это для лучшей безопасности кода/удобочитаемости.
Для меня int
- это тип, который не имеет особого значения: он может подсчитывать яблоки, бананы или что-то еще.
size_type
, который, вероятно, имеет значение typedef
для size_t
имеет более сильное значение: он указывает размер в байтах.
То есть легче узнать, что означает переменная. Конечно, следуя этому обоснованию, для разных единиц может быть много разных типов. Но "размер буфера" на самом деле является обычным делом, поэтому он каким-то образом заслуживает специального типа.
Другим аспектом является сохранение кода: если контейнер внезапно меняет свой size_type
скажем, uint64_t
на unsigned int
например, используя size_type
вам не нужно изменять его в каждом исходном коде, опираясь на него.
Ответ 5
В книге, которую вы читаете, говорится, что если вы хотите извлечь размер вектора типа double (например), вы должны сделать что-то вроде:
vector<double>::size_type vector_size;
vector_size = myVector.size();
Если в Java вы могли бы сделать
int vector_size;
vector_size = myVector.size();
Оба являются более низкими параметрами в C++. Первый - чрезвычайно подробный и небезопасный (в основном из-за неявных рекламных акций). Второй - подробный и крайне небезопасный (из-за диапазона номеров).
В C++ do
ptrdiff_t const vectorSize = myVector.size();
Обратите внимание, что
-
ptrdiff_t
, из заголовка stddef.h
, является подписанным типом, который гарантированно достаточно большой.
-
Инициализация выполняется в декларации (это лучше [стиль CN10]).
-
Для обеих переменных было применено одно и то же соглашение об именах.
Таким образом, правильная вещь короче и безопаснее.
Cheers & hth.,
Ответ 6
Вы можете использовать int
, чтобы типы были созданы для переносимости кода.