Структуры данных, которые не содержат непрерывный набор значений, известны как разреженные или сжатые структуры данных. Кажется, это то, что вы ищете.
Если это так, вы хотите разреженный вектор . Один из них реализован в boost, см. текст ссылки
Разреженные структуры обычно используются для сохранения памяти. Из описания вашей проблемы возможно, что вы на самом деле заботитесь не об использовании памяти, а об адресах элементов, которые еще не существуют (вам нужен контейнер с автоматическим изменением размера). В этом случае простое решение без внешних зависимостей выглядит следующим образом:
Создайте шаблонный класс, который содержит вектор и перенаправляет все векторные методы в него. Измените ваш оператор [], чтобы изменить размер вектора, если индекс выходит за границы.
// A vector that resizes on dereference if the index is out of bounds.
template<typename T>
struct resize_vector
{
typedef typename std::vector<T>::size_type size_type;
// ... Repeat for iterator/value_type typedefs etc
size_type size() const { return m_impl.size() }
// ... Repeat for all other vector methods you want
value_type& operator[](size_type i)
{
if (i >= size())
resize(i + 1); // Resize
return m_impl[i];
}
// You may want a const overload of operator[] that throws
// instead of resizing (or make m_impl mutable, but thats ugly).
private:
std::vector<T> m_impl;
};
Как отмечено в других ответах, элементы не очищаются при изменении размера вектора. Вместо этого, когда новые элементы добавляются изменением размера, вызывается их конструктор по умолчанию. Поэтому при использовании этого класса вам необходимо знать, что operator[]
может вернуть вам ссылку на созданный объект по умолчанию. Поэтому ваш конструктор по умолчанию для <T>
должен установить для объекта разумное значение для этой цели. Например, вы можете использовать значение Sentinel, если вам нужно знать, было ли элементу ранее присвоено значение.
Предложение использовать std::map<size_t, T>
также имеет смысл в качестве решения, если вы не возражаете против использования дополнительной памяти, несмежного хранения элементов и поиска O (logN), а не O (1) для вектора. Все это сводится к тому, хотите ли вы разреженное представление или автоматическое изменение размера; надеюсь, что этот ответ охватывает оба.