Does a std::allocator need to be default constructible?

Viewed 65

If I'm not missing something, according to the requirements of Allocator, the Allocatortemplate argument of a std::vector doesn't need to be default constructible.

However, the following minimal example doesn't compile (LIVE demo):

#include <vector>


template<typename T>
class stateful_allocator
{
public:
    using value_type = T;

    constexpr explicit stateful_allocator(int s) noexcept
        : m_state(s)
    {}

    template <typename U>
    stateful_allocator(stateful_allocator<U> const& other) noexcept {
        m_state = other.m_state;
    }

    T* allocate(std::size_t) { return nullptr; }
    void deallocate(T*, std::size_t) noexcept {}

private:
    int m_state;
};

template <typename T, typename U>
bool operator==(stateful_allocator<T> const&, stateful_allocator<U> const&) noexcept {
    return true;
}

template <typename T, typename U>
bool operator!=(stateful_allocator<T> const& x, stateful_allocator<U> const& y) noexcept {
    return !(x == y);
}


int main()
{
    std::vector<int, stateful_allocator<int>> x(0);
}
1 Answers

std::vector<int, stateful_allocator<int>> x(0) is calling the std::vector constructor overload which takes a size, not implicitly converting 0 to stateful_allocator (which you've disallowed anyway by marking your constructor explicit).

As you aren't passing in an allocator instance one is default constructed due to the default arguments in the constructor.

Try:

std::vector<int, stateful_allocator<int>> x(stateful_allocator<int>{0});
Related