Search code examples
c++inheritancememory-managementfinalallocator

Can a C++ allocator be final?


The cppreference page for the Allocator requirement does not say that an Allocator must be inheritable, i.e. it does not say that an Allocator must not be final.

However, in many libraries, an allocator is privately inherited to take advantage of the empty base class optimization for stateless allocators. For example:

template <typename T, typename A = std::allocator<T>>
class Dummy_vector :private A {
    // ...
    A get_alloc() const
    {
        return static_cast<A>(*this);
    }
    // ...
};

If A is final, this implementation breaks.

Can an Allocator be final? Did I miss something? Or should such implementation include special code for final Allocators?

(Note: by "special code for final Allocators," I mean something like this:

template <
    typename T,
    typename A = std::allocator<T>,
    bool = std::is_final<A>
>
class Dummy_vector :private A {
    // version for nonfinal allocators
    // ...
    A get_alloc() const
    {
        return static_cast<A>(*this);
    }
    // ...
};

template <typename T, typename A>
class Dummy_vector<T, A, true> {
    // special version for final allocators
};

)


Solution

  • This is indeed a problem. See also C++ Standard Library Defect Report 2112. The standard does not require that an allocator type can be derived from. However, the standard also doesn't specify that an implementation derive from the allocator type. Thus, the consensus seems to be that this is to be considered the implementation's fault for not checking whether the allocator type can be derived from…