Элегантное избегание инициализации значений векторных элементов в будущем C++?
Когда элементы вставляются по умолчанию в экземпляр std::vector<T>
, они инициализируются значением по умолчанию. Я часто работаю с многопоточными высокопроизводительными кодами, где такая инициализация значения для больших массивов может представлять собой недопустимое последовательное узкое место.
Типичный подход, основанный на reserve()
а также push_back()
/emplace_back()
бесполезно, если в параллельных кодах. Я обычно заканчиваю одним из следующих вариантов:
- определение пустого конструктора по умолчанию для
T
, - определение и использование пользовательского распределителя с пустым
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&&)
который делает размещение новым для вас {}
,