Reputation: 1066
I would like to customize std::vector
behavior to not default-construct the element type (e.g. int
), as it is expensive to do this for a large vector.
Looking at this, the only way I can see to do this is to specialize std::allocator_traits<MyAllocator>::construct
. However, this doesn't seem to be possible, because the specialization must be in the same namespace as the original declaration.
Putting a specialization in namespace std
already doesn't seem right. And it's actually worse than that, because the STL implementation I am using actually puts std::allocator_traits
in namespace std::__u
(and that surely varies across STL implementations), so it seems very wrong to do this.
This is confusing because it seems like std::allocator_traits is designed to allow specialization, but I can't figure out how to actually do it. Is this simply a bad idea? If so, is there some other way to solve the problem (avoiding default construction of elements in STL containers)?
Upvotes: 3
Views: 826
Reputation: 473447
Specializing standard library traits classes is not only allowed, it's the main way to provide such functionality. However, in this particular case, it is unnecessary.
The default std::allocator_traits<T>::construct
implementation (where T
is your allocator type, not the value-type of the container it is being used with) will call the construct
member function of T
if T
has such a function, and it calls placement-new
if T
doesn't have an appropriate member. So simply give your allocator a construct
member and you should be fine.
Upvotes: 4
Reputation: 2623
You should call reserve
and not resize
. Add element only when the value is known. There is no point to create a vector
full of garbage.
std::vector<int> v;
r.reserve(500);
v.push_back(3); // Only 1 constructor is called
If you really don't want to initialize the data but still fill it, then using a struct
with a constructor that do not initialize its member should do;
struct unintialized_int
{
unintialized_int() { /* no initialization */ }
int uninitialized;
};
std::vector<unintialized_int> v;
v.resize(500);
v[22].uninitialized = 33;
However, I would not recommend that as it can lead to hard to find bugs!
Better to use vector as intended.
By the way to have an impact on performance with trivial type like int
, you must have many thousand items or create thousand of vectors.
Some questions to ask yourself:
int
, the compiler is probably able to optimize the initialisation to a memset
.Upvotes: -2