Lets say I want to create a vector
and call iota
on it:
std::vector<int> v(1000);
std::iota(begin(v),end(v),0);
The vector is actually 0-initialized in the constructor. The problem would be the same with:
std::vector<int> v;
v.resize(1000);
I could use reserve
, but then I can't call iota
. And I see no elegant way to not zero-initialize (maybe with a custom allocator...?).
Why was vector
designed in such a way? I know that Stepanov and collaborators very carefully crafted the STL and there is very few flaws. But to me, it is one in the sense that it seems to conflict with "you don't pay for what you don't use". What was the motivation of such a design?
Is there a consensus that retrospectively, it should not have been done like that? (e.g. as it is the case with the unsigned size_t
used for size()
where people seem to agree that it should have been the same type as difference_type
because we are comparing indices and size()
so often).
More information
Performance
Some comparisons regarding the generated code. Does the compiler optimize the 0-init away? It is difficult to look at the assembler when using vector
because it does a lot of stuff so I tried this code:
int main() {
int* v = new int[1000]; // clearer for reading assembly
fill(v,v+1000,0);
iota(v,v+1000,0);
return v[999]; // do not optimize away!
}
Result here. Then with std::fill
removed
Simple enought right? Well the assembly is not the same with gcc or clang-O3
, and it is longer with std::fill
, which generally indicates that instructions are actually issued.
So unless I am misinterpreting, it does matter.
History
The code of the original STL can be found here. In version 2, the content of the vector was already default-initialized. It seems like the commitee validated what was already there.
Comparison to std::array
Some people in the comment believe that you absolutely must initialize the content of the vector. But the proof that this is really a design decision is the fact that std::array
, on the contrary, does not default-initialize its memory. So maybe it is easier, or makes more sense, to implement vector
and array
the way they are, but the other way around would have been possible, for both.