Подтвердить что ты не робот

Как зарезервировать память для std::vector во время строительства?

Обычно я вызываю reserve на std::vector сразу после его создания. Разве это обычно не приводило к уничтожению существующего распределения кучи std::vector и замене новым? Есть ли способ зарезервировать память во время строительства, а не выделять кучу пространства, а затем немедленно уничтожить ее? Или существует трюк внедрения в std::vector, чтобы гарантировать, что это не проблема?

Доступные конструкторы, по-видимому, могут быть полезны для заполнения значений std::vector, а не для резервирования пространства явно.

4b9b3361

Ответ 1

Ваш вопрос основан на ложной предпосылке, а именно, что построенный по умолчанию std::vector<T> будет выполнять распределение [нулевой длины].

В этом нет никаких оснований для этого. Свежий вектор должен иметь нулевую емкость (хотя это требуется по здравому смыслу, а не по стандарту).

Таким образом, ваша цель уже удовлетворена.

Чтобы быть тупым, стандартная библиотека не совсем такая глупа.

Ответ 2

Если количество элементов известно во время компиляции, вы можете перечислить-инициализировать вектор с такими элементами:

 class MyClass 
 {
      int x, y, z;
      std::vector<int> v;

  public:
         MyClass(int X, int Y, int Z) : x(X), y(Y), z(Z), v{x, y, z}
         {}
 };

Но это не очень приятно поддерживать. Существуют более совершенные методы, такие как пользовательские распределители, которые вы можете использовать для использования std::vector, которые могут использовать память из предварительно выделенного пула памяти, например: я сомневаюсь, что вам это действительно нужно. Современные реализации легко оптимизировали бы такую ​​простую задачу.

Ответ 3

Причина может быть иронической, у нас заканчивается сигнатура функции.

Требование исходит из сценария использования, который мы точно знаем, сколько элементов мы будем сохранять в вектор, но нам действительно не нравится конструктор n-duplicated elements:

std::vector( size_type count, const T& value = T())

К сожалению, подпись занята указанным выше конструктором. Любая другая возможная подпись может вызвать проблему. Например.

  • vector(size_type count, size_type reserve_count) будет конфликтующим с конструктором n-дублированных элементов для вектора T(size_type).

  • vector(size_type count, const T& value = T(), size_type reserve_count) - это возможное решение, но оно слишком длинное и все еще скучное. Нам нужно построить значение по умолчанию, которое мы никогда не используем при вызове auto v = vector<T>(0, T(), reserve_count)

Другие возможные решения:

  • Предоставляет функцию, например make_pair/make_unique.

  • Определяет Reserver, который получен из Allocator, поэтому мы можем использовать вектор конструктора (const Allocator & alloc), например

auto v = vector<Type>(new Reserver(reserve_count));

Ответ 4

Объект std::vector и его массив элементов не существует в одном и том же непрерывном блоке памяти, иначе его адрес будет меняться каждый раз при изменении размера массива, что делает невозможным сохранение надежной ссылки на него. Основной объект объекта содержит только контрольные переменные и указатель на фактический массив, и он будет установлен в стек (если вы используете его как локальную переменную) вместе с другими локальными переменными. И в это время массив будет пустым и, вероятно, представлен указателем на nullptr. Таким образом, неважно, если вы reserve во время построения или сразу после него не будет существенной оптимизации.

Если вы хотите, чтобы std::vector со статическим размером, который зарезервирован мгновенно, вы можете просто использовать обычный массив C вместо std::vector. Просто убедитесь, что он вписывается в стек.