c++c++11stlstdstdvector

Why does std::vector have 2 constructors instead of 1 with default argument?


I looked at cppreference.com and found this

vector();
explicit vector( const Allocator& alloc );

why not just

explicit vector(const Allocator& alloc = Allocator());

1 constructor instead of 2. Is there a reason for this? same with resize(std::size_t,const T& t) and resize(std::size_t) why not just resize(std::size_t,const T& t = T())


Solution

  • Regarding std::vector<T, Allocator>:
    For question one, it's a matter of utility and efficiency.
    For vector() with no argument:

    vector();
    

    The allocator object is supplied by the template, with the default being std::allocator.

    The definition may be written as:

    constexpr vector() : elem(nullptr), array_size(0), space(0) {}
    

    For vector with an allocator object supplied as an argument:

    constexpr explicit vector(const Allocator& alloc) noexcept;
    

    The definition may be written as:

    constexpr explicit vector(const Allocator& alloc) noexcept : elem(nullptr), array_size(0), space(0), v_alloc(alloc) {}
    

    Both will construct an empty vector. If "Allocator" is a custom allocator, i.e., "my_allocator", assigning the object via an argument, allows for characteristics that are different from an allocator object supplied by the template. When the allocator object is supplied by template, all values within the object have default values. When the allocator object is supplied as an argument, the allocator can be reconfigured before passing the object as an argument.

    When vector is constructed without an argument, the allocator is default constructed. When vector is constructed with an argument, the allocator is first default constructed, then copy assigned from the argument. Therefore, it would be less efficient to have one constructor with an argument that defaults to "(const Allocator& alloc = Allocator())".

    For question two, it's a matter of efficiency.

    "void resize(std::size_t count)" appends default elements when vector is resized larger. Each appended element is default constructed via std::allocator_traits:

    std::allocator_traits<decltype(v_alloc)>::construct(v_alloc, ptr);
    

    "void resize(std::size_t count, const T& value)" appends elements "value" with a copy constructor when the vector is resized larger.

    std::allocator_traits<decltype(v_alloc)>::construct(v_alloc, ptr, value)
    

    If "T()" were supplied as a default for "value", appended elements are copy constructed, rather than default constructed.