This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of NAD status.
Section: 16.4.4.6 [allocator.requirements] Status: NAD Submitter: Stephan T. Lavavej Opened: 2013-09-21 Last modified: 2016-01-28
Priority: 2
View other active issues in [allocator.requirements].
View all other issues in [allocator.requirements].
View all issues with NAD status.
Discussion:
C++11's minimized allocator requirements are great, but they're still requiring more things from users than absolutely necessary.
They require X::value_type, but that can be deduced from SomeAllocator<T, Args>.
They require a1 == a2, but that could default to true as most allocators are stateless.
They require a1 != a2, but if we start requiring STL implementations to go through allocator_traits to provide an op== default, we won't need to require op!= from users at all. (std::allocator, of course, would continue to provide op!=. Note that this is analogous to reference/const_reference — std::allocator still provides them, but we don't require them from users, and in fact we don't require them to be consistent or meaningful if present.)
They require a == b and a != b. This requirement was not present in C++98/03, it is not necessary (a == b is always required to be equivalent to rebind-then-compare), and STL implementations don't even need to compare allocators of different types directly.
[2014-02-14 Issaquah: Close as NAD]
Different vendors rely on each of the different elements suggested to be removed.
While value_type my be deduced as suggested, far too much wording relies on it being available, and the standard churn is likely to be much harder than presented here.
Proposed resolution:
This wording is relative to N3691.
Change in 16.4.4.6 [allocator.requirements], Table 28 — "Allocator requirements" as indicated:
Table 28 — Allocator requirements (continued) Expression Return type Assertion/note pre-/post-condition Default … X::value_type Identical to T See Note B, below. … a1 == a2 bool returns true only if storage
allocated from each can be
deallocated via the other.
operator== shall be reflexive,
symmetric, and transitive, and
shall not exit via an exception.
true a1 != a2boolsame as !(a1 == a2)a == bboolsame as a ==
Y::rebind<T>::other(b)a != bboolsame as !(a == b)… X a(b); Shall not exit via an exception.
post: Y(a) == b, a == X(b)… X a(move(b)); Shall not exit via an exception.
post: a equals the prior value of X(b).…
After 16.4.4.6 [allocator.requirements] p3, add a new paragraph:
Note B: If Allocator is a class template instantiation of the form SomeAllocator<T, Args>, where Args is zero or more type arguments, and Allocator does not supply a nested type named value_type, the standard allocator_traits template uses T in place of Allocator::value_type by default. For allocator types that are not template instantiations of the above form, no default is provided.
In the example provided in 16.4.4.6 [allocator.requirements]/5, delete as indicated:
template <class Tp> struct SimpleAllocator {typedef Tp value_type;SimpleAllocator(ctor args); template <class T> SimpleAllocator(const SimpleAllocator<T>& other); Tp *allocate(std::size_t n); void deallocate(Tp *p, std::size_t n); };template <class T, class U> bool operator==(const SimpleAllocator<T>&, const SimpleAllocator<U>&); template <class T, class U> bool operator!=(const SimpleAllocator<T>&, const SimpleAllocator<U>&);
Edit 20.2.9 [allocator.traits]p1, class template allocator_traits synopsis, as indicated:
namespace std { template <class Alloc> struct allocator_traits { typedef Alloc allocator_type; typedeftypename Alloc::value_typesee below value_type; […] static Alloc select_on_container_copy_construction(const Alloc& rhs); static bool equal(const Alloc& a1, const Alloc& a2) noexcept; }; }
At the beginning of 20.2.9.2 [allocator.traits.types], add a new paragraph:
typedef see below value_type;Type: Alloc::value_type if such a type exists; otherwise, T if Alloc is a class template instantiation of the form Alloc<T, Args>, where Args is zero or more type arguments; otherwise, the program is ill-formed.
At the end of 20.2.9.3 [allocator.traits.members], add a new paragraph:
static bool equal(const Alloc& a1, const Alloc& a2) noexcept;-?- Returns: a1 == a2 if that expression is well-formed; otherwise, true.