Типы векторных типов С++

Я только начал изучать 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, чтобы типы были созданы для переносимости кода.