1318. N2982 removes previous allocator capabilities

Section: 23.10.9.1 [allocator.traits.types] Status: NAD Submitter: Pete Becker Opened: 2010-02-11 Last modified: 2016-02-10

Priority: Not Prioritized

View all issues with NAD status.

Duplicate of: 1375

Discussion:

Addresses US-87

N2982 says that containers should have a nested typedef that defines their reference_type as value_type&; the previous standard deferred to the allocator to define its reference_type, and containers simply passed the allocator's typedef on. This change is a mistake. Allocators should define both a pointer type and a reference type. That's essential for their original purpose, which was to make different memory models transparent. If an allocator defines a pointer type that isn't compatible with a normal pointer it also has to define a corresponding reference type. For example (and please forgive a Windows-ism), if an allocator's pointer is T __far*, then it's reference has to be T __far&. Otherwise everything crashes (under the hood, references are pointers and have to have the same memory access mechanics). Extensions such as this for more general memory models were explicitly encouraged by C++03, and the allocator's pointer and reference typedefs were the hooks for such extensions. Removing the allocator's reference and const_reference typedefs makes those extensions unimplementable and breaks existing implementations that rely on those hooks.

[ 2010-02-25 Alisdair adds: ]

vector<bool>::reference is a nested class, and not a typedef. It should be removed from the list of containers when this change is made.

In general, I am uncomfortable placing this reference requirement on each container, as I would prefer to require:

is_same<Container::reference, Container::iterator::reference>

This distinction is important, if we intend to support proxy iterators. The iterator paper in the pre-Pittsburgh mailing (N3046) does not make this proposal, but organises clause 24 in such a way this will be much easier to specify.

The changes to clause 20 remain important for all the reasons Pete highlights.

[ 2010 Batavia ]

Removed vector from list of templates that should be adjusted as of meeting outcome.

[ 2010 post-Batavia ]

Replaced vector<bool> reference by vector reference because of misinterpreting meeting typo. Additional corrected numbering in P/R to N3225 wording.

[ 2010-12-06 Daniel reopens ]

Unfortunately, the current P/R is defective for several reasons:

  1. Table 43 — Descriptive variable definitions still contains three references to T&, namely in:
    t a value of type const T&
    r a value of type T& obtained by the expression *p
    s a value of type const T& obtained by the expression *q or by conversion from a value r
    Especially the second and third items are misses in the 1318 P/R, e.g. in N2723 or in C++03 these were referring to X::reference and X::const_reference, resp. None of them is referenced anywhere in the allocator requirements table: r and s where historically needed to define the expressions a.address(r) and a.address(s) which are gone now, and t was needed to define the expression a.construct(p, t) which has been replaced by a.construct(p,args).

    The easiest fix seems to be to remove all three rows from Table 43.

  2. Further-on, the current P/R suggests to replace the the current definitions of the adaptor classes
    stack
    priority_queue
    queue
    
    similar to the other container types, i.e. to define reference and const_reference now as
    typedef typename allocator_traits<Allocator>::reference reference;
    typedef typename allocator_traits<Allocator>::const_reference const_reference;
    
    This would not only be an ill-formed definition (because there is no name Allocator in scope), but it would also introduce a breakage compared to C++03, where these definitions where already referring to the definition of the wrapped containers. So, the adaptor class templates should be removed from the current list.
  3. Then the current P/R wording leads to one further unexpected and unwanted change due to the general formular used: match_result::reference is currently defined as
    typedef const_reference reference;
    
    because it is an immutable container (And we had this definition already in N2723). The application of the rule would change this silently.
  4. Finally the suggested wording for the unordered_ containers is incomplete. The reason is a current inconsistency between these containers and the rest: While normally the definition of the pointer types is
    typedef typename allocator_traits<Allocator>::pointer pointer;
    typedef typename allocator_traits<Allocator>::const_pointer const_pointer;
    
    for the unordered containers they are
    typedef typename allocator_type::pointer pointer;
    typedef typename allocator_type::const_pointer const_pointer;
    
    These definitions are not equivalent, because allocators are no longer required to define typedefs pointer and const_pointer, the allocator_traits were invented as a further indirection to cope with that. I.e. for the unordered containers we need to bring both the definition of references and pointers in sync.

[ 2011-02-23 Daniel updates the proposed wording with support from Pablo ]

The update attempts to fix the backward-compatibility problem that we have introduced by ignoring the C++03 member function overloads address of allocator types in C++0x completely. The resolution attempts to fix that by adding these functions as optional members of allocators that are considered first before falling back to pointer_traits::pointer_to. This still allows us to remove the unused symbol t from the table, but we adapt the symbols r and s to purely refer to the typenames reference and const_reference.

[2011-03-06 Daniel adapts numbering to N3242]

[2011-03-11 Daniel removes noexcept specifiers from address functions]

[2011-03-12 Further wording improvements by Daniel and Pablo]

[2011-03-22 Madrid]

Closed as NAD, no consensus to make a change

Rationale:

No consensus to make a change

Proposed resolution: