Использование вектора в качестве буфера без его инициализации при изменении размера ()
Я хочу использовать vector
в качестве буфера. Интерфейс идеально подходит для моих нужд, но при изменении размера его размера до тех пор, пока память не будет инициализирована, есть ограничение производительности. Мне не нужна инициализация, так как данные будут перезаписаны в любом случае некоторыми сторонними функциями C. Есть ли способ или конкретный распределитель, чтобы избежать шага инициализации? Обратите внимание, что я хочу использовать resize()
, а не другие трюки, такие как reserve()
и capacity()
, потому что мне нужно, чтобы size()
всегда представлял значимый размер моего «буфера» в любой момент, а capacity()
может быть больше, чем его размер после resize()
, поэтому, опять же, я не могу полагаться на capacity()
как значительную информацию для моего приложения. Furthemore, (новый) размер вектора никогда не известен заранее, поэтому я не могу использовать std::array
. Если вектор не может быть настроен таким образом, я хотел бы знать, какой контейнер или распределитель я мог бы использовать вместо vector
. Единственное требование состоит в том, что альтернатива вектору должна быть в лучшем случае основана на STL или Boost. У меня есть доступ к C ++ 11.
- Почему изменение строки через извлеченный указатель на его данные не разрешено?
- std :: next_permutation Объяснение реализации
- Что такое std :: prom?
- Несколько проблем «не удалось решить» с помощью Eclipse с minGW
- Почему «std :: vector b {2}; ' создать 1-элементный вектор, а не 2-элементный?
- C ++ Qt - Как добавить «-std = c ++ 11» в make-файл, который генерируется qmake?
- shared_ptr относится к weak_ptr как unique_ptr для ... чего?
- to_string не является членом std, говорит g ++ (mingw)
В стандартной библиотеке нет ничего, что бы соответствовало вашим требованиям, и я ничего не знаю об этом.
Есть три разумных варианта, о которых я могу думать:
- Придерживайтесь
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
.