Created on 2016-10-14.00:00:00 last changed 90 months ago
Proposed resolution:
This wording is relative to N4606.
Modify [allocator.adaptor.cnstr] by converting "Requires" elements to "Remarks: shall not participate ..." constraints as shown:
template <class OuterA2> scoped_allocator_adaptor(OuterA2&& outerAlloc, const InnerAllocs&... innerAllocs) noexcept;-3- Effects: Initializes the OuterAlloc base class with std::forward<OuterA2>(outerAlloc) and inner with innerAllocs... (hence recursively initializing each allocator within the adaptor with the corresponding allocator from the argument list). -?- Remarks: This constructor shall not participate in overload resolution unless is_constructible_v<OuterAlloc, OuterA2> is true. […]
-2- Requires: OuterAlloc shall be constructible from OuterA2.template <class OuterA2> scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other) noexcept;-7- Effects: Initializes each allocator within the adaptor with the corresponding allocator from other. -?- Remarks: This constructor shall not participate in overload resolution unless is_constructible_v<OuterAlloc, const OuterA2&> is true.
-6- Requires: OuterAlloc shall be constructible from OuterA2.template <class OuterA2> scoped_allocator_adaptor(scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other) noexcept;-9- Effects: Initializes each allocator within the adaptor with the corresponding allocator rvalue from other. -?- Remarks: This constructor shall not participate in overload resolution unless is_constructible_v<OuterAlloc, OuterA2> is true.
-8- Requires: OuterAlloc shall be constructible from OuterA2.
[ 2016-11-12, Issaquah ]
Sat AM: Priority 0; move to Ready
Billy to open another issue about the confusion with the ctor
The templated constructors of scoped_allocator_adaptor need to be constrained, otherwise uses-allocator construction gives the wrong answer and causes errors for code that should compile.
Consider two incompatible allocator types:template<class T> struct Alloc1 { ... }; template<class T> struct Alloc2 { ... }; static_assert(!is_convertible_v<Alloc1<int>, Alloc2<int>>);
The unconstrained constructors give this bogus answer:
template<class T> using scoped = scoped_allocator_adaptor<T>; static_assert(is_convertible_v<scoped<Alloc1<int>>, scoped<Alloc2<int>>>);
This causes uses_allocator to give the wrong answer for any specialization involving incompatible scoped_allocator_adaptors, which makes scoped_allocator_adaptor::construct() take an ill-formed branch e.g.
struct X { using allocator_type = scoped<Alloc2<int>>; X(const allocator_type&); X(); }; scoped<Alloc1<int>>{}.construct((X*)0);
This fails to compile, because uses_allocator<X, scoped_allocator_adaptor<Alloc2<int>>> is true, so the allocator is passed to the X constructor, but the conversion fails. The error is outside the immediate context, and so is a hard error.
History | |||
---|---|---|---|
Date | User | Action | Args |
2017-07-30 20:15:43 | admin | set | status: wp -> c++17 |
2017-03-05 23:41:16 | admin | set | status: ready -> wp |
2016-11-21 05:09:01 | admin | set | messages: + msg8665 |
2016-11-21 05:09:01 | admin | set | status: new -> ready |
2016-10-15 12:31:44 | admin | set | messages: + msg8563 |
2016-10-14 00:00:00 | admin | create |