https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91541
--- Comment #3 from frankhb1989 at gmail dot com --- (In reply to Jonathan Wakely from comment #2) > (In reply to frankhb1989 from comment #0) > > This type does not meet the allocator requirements. For a valid allocator, > A::rebind<A::value_type>::other must be the same type as A, and > A::rebind<U>::other::rebind<A::value_type>::other must also be the same type > as A. Oops, I missed those requirements. How about this? #include <utility> #include <map> #include <functional> using P = std::pair<const int, int>; template<typename T> struct AT { using value_type = T; template<typename U> struct rebind { using other = AT<U>; }; using is_always_equal = std::is_same<T, P>; template<typename U> AT(const AT<U>&); T* allocate(std::size_t); void deallocatoe(T*, std::size_t); }; using A = AT<P>; int main() { static_assert(std::is_same_v<A::template rebind<A::value_type>::other, A>); // For any U: using U = int; static_assert(std::is_same_v<A::template rebind<U>::other::template rebind<A::value_type>::other, A>); using always_equal = std::allocator_traits<A>::is_always_equal; using C = std::less<>; constexpr bool std_nothrow = always_equal::value && std::is_nothrow_move_assignable_v<C>; static_assert(std_nothrow); static_assert(!(std_nothrow && !std::is_nothrow_move_assignable<std::map<int, int, C, A>>::value)); }