Reputation: 23497
When elements are default-inserted into an instance of std::vector<T>
, they are value-initialized by default. I often work with multi-threaded high-performance codes, where such value-initialization might for large arrays represent an unacceptable sequential bottleneck.
The typical approach based on reserve()
and push_back()
/emplace_back()
is of no use if in concurrent codes. I usually end up with one of the following options:
T
,construct()
member function. However, both solutions are far from being elegant and also have drawbacks. The former cannot be used for T
being a POD type, such as double
. The latter requires a given implementation of the C++ Standard Library to supoort the relatively new DefaultInsertable
concept. Moreover, definition of a custom allocator is quite tedious.
Is there any chance that in the future of C++ there will be some straightforward way how to "turn off" this default-insertion/value-initialization?
UPDATE
Mayebe, I should've asked simply if it will be possible to avoid zero-initialization of default-inserted elements of a vector for arithmetic types.
Upvotes: 3
Views: 594
Reputation: 275330
Vector is poorly suited to your needs. It supports resizing and accidental copy, neither of which make sense in a multi-threaded environment.
Write a simple container:
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;
};
Populate it with container-esque begin/end/front/size/[]
/empty etc.
Make it move only.
Use rule of zero (with =default
).
Give it a explicit buffer(std::size_t)
ctor that creates its content uninitialized.
Mix in some span/array_view types, and this should be suitable for your needs.
Maybe have emplace(size_t,Args&&)
which does placement new for you with {}
.
Upvotes: 3