почему это не шаблонно?
Поскольку стандартные контейнеры реализованы так, чтобы использовать самый большой тип без знака, который они могут разумно использовать.Если size_type
равно unsigned int
в вашей реализации, то по какой-то причине, и какова бы ни была причина, препятствующая реализации, использующей больший тип, все равно будет существовать, если вы попросите что-то еще [*].Кроме того, в вашем конкретном примере типы размеров должны быть без знака, и вы хотите использовать тип со знаком, так что это еще одно изменение, которое потребуется для поддержки того, что вы хотите сделать.
На практике size_type
для стандартного контейнера (почти?) всегда size_t
.Поэтому, если вы запросили больший вектор, у вас его не было бы, потому что вектор поддерживается непрерывным хранилищем.Вектор не сможет выделить массив размером более size_t
байтов.
Чтобы использовать Id
в качестве векторного индекса, вы можете либо полагаться на неявные преобразования, либо вы можете явно преобразовать (и, возможно,явно проверьте границы), чтобы было абсолютно ясно, что вы делаете.Вы также можете использовать утверждения, чтобы убедиться, что Id
не больше size_type
.Примерно так, хотя статическое утверждение, вероятно, было бы лучше:
assert(std::numeric_limits<Id>::max() <= std::numeric_limits<std::vector<SomeObj*>::size_type>::max());
A map<Id, SomeObj*>
было бы хорошим вариантом, если используемые значения Id бывают разреженными.Если единственными допустимыми идентификаторами являются 1 и 400 000 000, то вектор будет довольно бесполезно использовать память.
Если вам от этого легче, помните, что литерал 0
имеет тип int
, а не vector<SomeObj*>::size_type
.Большинство людей не сомневаются в написании vec[0]
: на самом деле это используется в стандарте.
[*] Даже если эта причина проста, «разработчики считают, что 4 миллиарда элементов достаточно для любого».