Is a cv-qualified pair specially handled in uses-allocator construction?
Jiang An

Created on 2022-02-16.00:00:00 last changed 10 months ago


Date: 2022-11-17.00:42:33

Proposed resolution:

This wording is relative to N4917.

  1. Modify [allocator.uses.construction] as indicated, using remove_cv_t in every Constraints: element (paragraphs 4, 6, 8, 10, 12, 14, 17):

    Constraints: remove_cv_t<T> [is|is not] a specialization of pair

  2. Add remove_cv_t in paragraph 5:

    -5- Returns: A tuple value determined as follows:

    (5.1) — If uses_allocator_v<remove_cv_t<T>, Alloc> is false and is_constructible_v<T, Args...> is true, return forward_as_tuple(std::forward<Args>(args)...).

    (5.2) — Otherwise, if uses_allocator_v<remove_cv_t<T>, Alloc> is true and is_constructible_v<T, allocator_arg_t, const Alloc&, Args...> is true, return

    tuple<allocator_arg_t, const Alloc&, Args&&...>(
      allocator_arg, alloc, std::forward<Args>(args)...)

    (5.3) — Otherwise, if uses_allocator_v<remove_cv_t<T>, Alloc> is true and is_constructible_v<T, Args..., const Alloc&> is true, return forward_as_tuple(std::forward<Args>(args)..., alloc).

    (5.4) — Otherwise, the program is ill-formed.

  3. Rephrase paragraph 7 in terms of the pair member types:

    -?- Let T1 be T::first_type. Let T2 be T::second_type.

    -6- Constraints: remove_cv_t<T> is a specialization of pair

    -7- Effects:: For T specified as pair<T1, T2>, equivalent Equivalent to:

Date: 2022-11-12.00:00:00

[ 2022-11-12 Approved at November 2022 meeting in Kona. Status changed: Voting → WP. ]

Date: 2022-09-15.00:00:00

[ 2022-09-30; moved to Tentatively Ready after seven votes in reflector poll ]

Date: 2022-09-15.00:00:00

[ 2022-09-23; Jonathan provides improved wording ]

Date: 2022-08-15.00:00:00

[ 2022-08-25; Jonathan Wakely provides wording ]

Previous resolution [SUPERSEDED]:

This wording is relative to N4910.

  • Modify [allocator.uses.construction] as indicated, using remove_cv_t in every Constraints: element:

    Constraints: remove_cv_t<T> [is|is not] a specialization of pair

Date: 2022-08-15.00:00:00

[ 2022-08-24; LWG telecon ]

Change every T to remove_cv_t<T>.

Date: 2022-03-15.00:00:00

[ 2022-03-04; Reflector poll ]

Set priority to 2 after reflector poll.

Date: 2022-02-16.00:00:00

It seems unclear whether cv-qualified pair specializations are considered as specializations of pair in [allocator.uses.construction].

Currently MSVC STL only considered cv-unqualified pair types as such specializations, while libstdc++ accept both cv-unqualified and const-qualified pair types as such specializations. The resolution of LWG 3525 uses remove_cv_t, which possibly imply that the specialization of pair may be cv-qualified.

The difference can be observed via the following program:

#include <utility>
#include <memory>
#include <vector>
#include <cassert> 

template<class T>
class payload_ator {

  int payload{};
  payload_ator() = default;

  constexpr explicit payload_ator(int n) noexcept : payload{n} {}

  template<class U>
  constexpr explicit payload_ator(payload_ator<U> a) noexcept : payload{a.payload} {}   

  friend bool operator==(payload_ator, payload_ator) = default;

  template<class U>
  friend constexpr bool operator==(payload_ator x, payload_ator<U> y) noexcept
    return x.payload == y.payload;

  using value_type = T;

  constexpr T* allocate(std::size_t n) { return std::allocator<T>{}.allocate(n); }

  constexpr void deallocate(T* p, std::size_t n) { return std::allocator<T>{}.deallocate(p, n); }   

  constexpr int get_payload() const noexcept { return payload; }

bool test()
  constexpr int in_v = 42;
  using my_pair_t = std::pair<int, std::vector<int, payload_ator<int>>>;
  auto out_v = std::make_obj_using_allocator<const my_pair_t>(payload_ator<int>{in_v}).second.get_allocator().get_payload();
  return in_v == out_v;

int main()
  assert(test()); // passes only if a const-qualified pair specialization is considered as a pair specialization
Date User Action Args
2022-11-17 00:42:33adminsetmessages: + msg13053
2022-11-17 00:42:33adminsetstatus: voting -> wp
2022-11-08 03:46:49adminsetstatus: ready -> voting
2022-10-06 17:09:10adminsetmessages: + msg12840
2022-10-06 17:09:10adminsetstatus: open -> ready
2022-09-23 22:47:01adminsetmessages: + msg12806
2022-08-25 19:38:43adminsetmessages: + msg12716
2022-08-25 19:38:43adminsetmessages: + msg12715
2022-08-25 19:38:43adminsetmessages: + msg12714
2022-08-25 19:38:43adminsetstatus: new -> open
2022-03-04 14:33:52adminsetmessages: + msg12400
2022-02-16 00:00:00admincreate