I think that libstdC ++ and libC ++ do exactly what the standard requires for the OP example.
uses_allocator<use_arg, allocator<use_arg>> true, but is_constructible<use_arg, allocator_arg_t, inner_allocator_type, int> is false because use_arg not constructive from the value allocator r, so the construct call must be poorly formed.
However, I believe that this is a defect in the standard. Consider this type:
struct use_arg { using allocator_type = std::allocator<use_arg>; use_arg(allocator_type&&) { } };
The uses_allocator and is_constructible are true, but scoped_allocator_adaptor::construct(pointer) calls are not compiled.
It is not is_constructible<T, inner_allocator_type> to check is_constructible<T, inner_allocator_type> (which checks the construction from rvalue allocator), but then pass inner_allocator_type& (which is lvalue), but that is what the standard says.
source share