Элегантное избегание инициализации значений векторных элементов в будущем C++?

Когда элементы вставляются по умолчанию в экземпляр std::vector<T>, они инициализируются значением по умолчанию. Я часто работаю с многопоточными высокопроизводительными кодами, где такая инициализация значения для больших массивов может представлять собой недопустимое последовательное узкое место.

Типичный подход, основанный на reserve() а также push_back()/emplace_back() бесполезно, если в параллельных кодах. Я обычно заканчиваю одним из следующих вариантов:

  1. определение пустого конструктора по умолчанию для T,
  2. определение и использование пользовательского распределителя с пустым construct() функция-член.

Тем не менее, оба решения далеко не элегантны, а также имеют недостатки. Первый не может быть использован для T будучи типом POD, таким как double, Последнее требует определенной реализации Стандартной библиотеки C++ для поддержки относительно новой DefaultInsertable концепция. Более того, определение пользовательского распределителя довольно утомительно.

Есть ли вероятность, что в будущем C++ будет какой-то простой способ, как "отключить" эту инициализацию по умолчанию при вставке / значении?

ОБНОВИТЬ

Может быть, я должен был просто спросить, можно ли будет избежать инициализации нулями вставляемых по умолчанию элементов вектора для арифметических типов.

1 ответ

Вектор плохо подходит для ваших нужд. Он поддерживает изменение размера и случайное копирование, что не имеет смысла в многопоточной среде.

Напишите простой контейнер:

 template<class T,class Storage=std::aligned_storage_t<sizeof(T),alignof(T)>{
 struct buffer{
   static_assert(std::is_pod<T)::value, "pod only");
   std::size_t count;
   std::unique_ptr<Storage[]> storage;
 };

Заполните его контейнером esque begin / end / front / size /[]/ пусто и т. д.

Заставь его двигаться только.

Использовать правило нуля (с =default).

Дать ему explicit buffer(std::size_t) ctor, который создает свой контент неинициализированным.

Смешайте несколько типов span / array_view, и это должно соответствовать вашим потребностям.

Может быть, есть emplace(size_t,Args&&) который делает размещение новым для вас {},

Другие вопросы по тегам