Использование вектора в качестве буфера без его инициализации при изменении размера ()

Я хочу использовать vector в качестве буфера. Интерфейс идеально подходит для моих нужд, но при изменении размера его размера до тех пор, пока память не будет инициализирована, есть ограничение производительности. Мне не нужна инициализация, так как данные будут перезаписаны в любом случае некоторыми сторонними функциями C. Есть ли способ или конкретный распределитель, чтобы избежать шага инициализации? Обратите внимание, что я хочу использовать resize() , а не другие трюки, такие как reserve() и capacity() , потому что мне нужно, чтобы size() всегда представлял значимый размер моего «буфера» в любой момент, а capacity() может быть больше, чем его размер после resize() , поэтому, опять же, я не могу полагаться на capacity() как значительную информацию для моего приложения. Furthemore, (новый) размер вектора никогда не известен заранее, поэтому я не могу использовать std::array . Если вектор не может быть настроен таким образом, я хотел бы знать, какой контейнер или распределитель я мог бы использовать вместо vector . Единственное требование состоит в том, что альтернатива вектору должна быть в лучшем случае основана на STL или Boost. У меня есть доступ к C ++ 11.

В стандартной библиотеке нет ничего, что бы соответствовало вашим требованиям, и я ничего не знаю об этом.

Есть три разумных варианта, о которых я могу думать:

  • Придерживайтесь std::vector , оставляйте комментарий в коде и возвращайтесь к нему, если это когда-либо вызывает узкое место в вашем приложении.
  • Используйте настраиваемый распределитель с пустым construct / методом destroy – и надейтесь, что ваш оптимизатор будет достаточно умным, чтобы удалить любые вызовы.
  • Создайте оболочку вокруг динамически распределенного массива, реализуя только минимальную функциональность, которая вам нужна.

Известно, что инициализация не может быть отключена даже явно для std::vector .

Обычно люди реализуют свой собственный pod_vector<> , который не выполняет инициализацию элементов.

Другой способ – создать тип, совместимый с маской с char, конструктор которого ничего не делает:

 struct NoInitChar { char value; NoInitChar() { // do nothing static_assert(sizeof *this == sizeof value, "invalid size"); static_assert(__alignof *this == __alignof value, "invalid alignment"); } }; int main() { std::vector v; v.resize(10); // calls NoInitChar() which does not initialize // Look ma, no reinterpret_cast<>! char* beg = &v.front().value; char* end = beg + v.size(); } 

Инкапсулируйте его.

Инициализируйте его до максимального размера (не резерв).

Сохраните ссылку на iterator, представляющий конец реального размера , как вы выразились.

Для ваших алгоритмов используйте begin и real end , а не end .

  • Где я могу использовать alignas () в C ++ 11?
  • Почему я должен использовать указатель, а не сам объект?
  • Различия между unique_ptr и shared_ptr
  • std :: enable_if условно скомпилировать функцию-член
  • Почему я не могу создать вектор lambdas (одного типа) в C ++ 11?
  • Использование адаптеров Boost с C ++ 11 lambdas
  • C ++ 11 auto: что, если он получает постоянную ссылку?
  • Как специализировать std :: hash :: operator () для пользовательского типа в неупорядоченных контейнерах?
  • C ++ 11 static_assert и создание шаблона
  • Можно ли использовать std :: string в constexpr?
  • Как вызвать функцию во всех вариационных шаблонных аргументах?
  • Давайте будем гением компьютера.