2103. std::allocator_traits<std::allocator<T>>::propagate_on_container_move_assignment

Section: 20.2.10 [default.allocator] Status: C++14 Submitter: Ai Azuma Opened: 2011-11-08 Last modified: 2016-01-28

Priority: Not Prioritized

View other active issues in [default.allocator].

View all other issues in [default.allocator].

View all issues with C++14 status.

Discussion:

"std::allocator_traits<std::allocator<T>>::propagate_on_container_move_assignment::value" is specified as "false", according to (20.2.10 [default.allocator]) and (20.2.9.2 [allocator.traits.types]). However, according to (23.2.2 [container.requirements.general]), this specification leads to the unneeded requirements (MoveInsertable and MoveAssignable of the value type) on the move assignment operator of containers with the default allocator.

Proposed resolution:

Either of the following two changes;

  1. adding the nested typedef like "typedef std::true_type propagate_on_container_move_assignment;" in the definition of std::allocator class template,
  2. adding the explicit partial specialization of "std::allocator_traits" class template for "std::allocator" class template, in which "propagate_on_container_move_assignment" nested typedef is specified as "std::true_type".

Pablo prefers the first resolution.

[2011-12-02: Pablo comments]

This issue has potentially some overlap with 2108. Should the trait always_compare_equal been added, this issue's resolution should be improved based on that.

[2012, Kona]

Move to Ready.

[2012, Portland: applied to WP]

Proposed resolution:

This wording is relative to the FDIS.

Change 20.2.10 [default.allocator], the class template allocator synopsis as indicated:

namespace std {
  template <class T> class allocator;

  // specialize for void:
  template <> class allocator<void> {
  public:
    typedef void* pointer;
    typedef const void* const_pointer;
    // reference-to-void members are impossible.
    typedef void value_type;
    template <class U> struct rebind { typedef allocator<U> other; };
  };

  template <class T> class allocator {
  public:
    typedef size_t size_type;
    typedef ptrdiff_t difference_type;
    typedef T* pointer;
    typedef const T* const_pointer;
    typedef T& reference;
    typedef const T& const_reference;
    typedef T value_type;
    template <class U> struct rebind { typedef allocator<U> other; };
    typedef true_type propagate_on_container_move_assignment;

    […]
  };
}