is_always_equal added to std::allocator makes the standard library treat derived types as always equal
Billy O'Neal III

Created on 2018-11-29.00:00:00, last changed 2019-02-18.00:16:57.


Date: 2019-02-18.00:16:57

Proposed resolution:

This wording is relative to N4778.

  1. Modify [default.allocator] as follows:

    -1- All specializations of the default allocator satisfy the allocator completeness requirements ([allocator.requirements.completeness]).

    namespace std {
      template<class T> class allocator {
        using value_type = T;
        using size_type = size_t;
        using difference_type = ptrdiff_t;
        using propagate_on_container_move_assignment = true_type;
        using is_always_equal = true_type;
        constexpr allocator() noexcept;
        constexpr allocator(const allocator&) noexcept;
        template<class U> constexpr allocator(const allocator<U>&) noexcept;
        allocator& operator=(const allocator&) = default;
        [[nodiscard]] T* allocate(size_t n);
        void deallocate(T* p, size_t n);

    -?- allocator_traits<allocator<T>>::is_always_equal::value is true for any T.

Date: 2019-02-18.00:16:57

[ 2019-02 Priority set to 2 after reflector discussion ]

Date: 2018-11-29.00:00:00

I (Billy O'Neal) attempted to change MSVC++'s standard library to avoid instantiating allocators' operator== for allocators that are declared is_always_equal to reduce the number of template instantiations emitted into .objs.

In so doing I introduced an unrelated bug related to POCMA handling, but it brought my attention to this allocator. This allocator doesn't meet the allocator requirements because it is getting std::allocator's operator== and operator!= which don't compare the root member. However, if this had been a conforming C++14 allocator with its own == and != we would still be treating it as is_always_equal, as it picks that up by deriving from std::allocator.

std::allocator doesn't actually need is_always_equal because the defaults provided by allocator_traits will say true_type for it, since implementers don't make std::allocator stateful.

Billy O'Neal thinks this is NAD on the grounds that we need to be able to add things or change the behavior of standard library types.

Stephan T Lavavej thinks we should resolve this anyway because we don't know of an implementation for which this would change the default answer provided by allocator_traits.

Date User Action Args
2019-02-18 00:16:57adminsetmessages: + msg10310
2018-12-01 16:18:24adminsetmessages: + msg10243
2018-11-29 00:00:00admincreate