When I step-debug through the code and look at Container.capacity() after every call to emplace(), the capacity sometimes increase by 0 (after inserting 4'th item) and sometimes increase by 1 (after inserting 5'th item).
I thought the capacity doubles every time resizing needs to be done.
Edited:
I ran it again using the "Run Code" feature of cpp.sh and got a different output. It looks like the reallocation scheme could be machine dependent.
Indeed, the implementation of how exactly the re-allocations occur is not standardized.
Also, while I can't confirm this, I imagine that calling emplace_back would be more efficient than emplace (probably less checks need to be done, even if you're back inserting already).
Also, the constructor initializer list can be used for copy ctors as well.
I thought the capacity doubles every time resizing needs to be done.
It would be nice if we could give them the resize function or at least give them a multiplier eg 1.10 (10% increase) etc.
double every time can be extremely wasteful once you get into large data, using at worst about twice what is needed at times which is going to start to have impact with data > 1gb or so
That's because the code I'd used wasn't an example to demonstrate how the capacity changes when reallocation occurs. I was actually interested in the number of times A's copy-constructor gets called and was surprised when it was called immediately after the second call to emplace().
As I'd figured out, this happened because of automatic resizing. After some step-debugging, I thought how incredibly wasteful the number of copy-ctor invocation just to emplace 8 elements and came here to ask about it.
I agree, your example is more concise at illustrating the allocation scheme. My code snippet does show when copy-ctor is called to copy over old elements when reallocation occurs. On my system, the output is:
As I'd figured out, this happened because of automatic resizing. After some step-debugging, I thought how incredibly wasteful the number of copy-ctor invocation just to emplace 8 elements and came here to ask about it.
This class probably would benefit from a move constructor. Don't forget to make it noexcept.
That's because the code I'd used wasn't an example to demonstrate how the capacity changes when reallocation occurs. I was actually interested in the number of times A's copy-constructor gets called and was surprised when it was called immediately after the second call to emplace().
The copies (or moves) are coupled to the reallocations. Showing both shines more light:
The restriction on the implementation is that push_back() must take constant amortized time. That means the vector can't grow by a constant amount. It must(?) grow by some multiple of the current size.
If you're worried about memory usage for a large vector, use reserve(). In my experience, you usually have an order-of-magnitude idea of the vector's size ahead of time. Reserve that much space, read the data into the vector, then call reserve again to trim it to an appropriate size.