How does std::vector allocate objects? It would seem as if it just uses std::allocator::allocate to create a block of memory, but then never calls std::allocate::construct. Is this true? Does std::vector only allocate memory and never construct the objects as memory allocation?
What if there is no default constructor? How is the constructor called when there is no default constructor on the object? What if there is more than one parameter?
For example, with this code there is no default constructor and std::allocator allows it.
#include <vector>
using namespace std;
class A{
protected:
int m;
public:
explicit A(int a) : m(a) { }
};
int main(){
vector<A> test;
return 0;
}
This has rather changed since C++11.
In C++03,
constructcould only perform copy-construction in-place.However, note that
std::vectorin particular is an array of objects, but there is a distinct size and capacity. That is, there can be more empty elements beyond the end of the part of the array that contains useful data.That is why the standard library’s allocator has a separation between “construction” and “memory allocation.” The
allocatordoes do both, but not at the same time. This allowsstd::vectorto allocate more memory than it uses. When you add new elements, it doesn’t necessarily have to allocate more memory; it can just use the spare memory it has left over via a call toallocator::construct.Also, note that all of the C++03 functions that add elements to
std::vectortake an element as a parameter.push_back,insert, even the sized constructor takes as a value as an argument. Yes, it’s a default parameter, but it still takes a value as an element. This element is copied into the vector, using a call to the allocator’sconstructmethod which takes a copy.In C++11, standard containers are required to use the
allocator_traits<>::constructfunction. This is a varadic function that forwards its parameters to the actual construct. This traits function will (by default. It can be specialized) call theallocator::constructmethod if that call is well-formed. If it isn’t, it will try placementnew.This allows for the new
emplacefunctions to work.But yes, the objects contained in standard library containers are in fact constructed objects. Even if the allocator’s
constructmethod is not called.