This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++23 status.
uses_allocator_construction_args should have overload for pair-likeSection: 20.2.8.2 [allocator.uses.construction] Status: C++23 Submitter: Tim Song Opened: 2022-11-08 Last modified: 2023-11-22
Priority: 2
View other active issues in [allocator.uses.construction].
View all other issues in [allocator.uses.construction].
View all issues with C++23 status.
Discussion:
P2165R4 added a pair-like constructor to
std::pair but didn't add a corresponding uses_allocator_construction_args overload.
It was in P2165R3 but incorrectly removed during the small group review.
pair-like into a
pmr::vector<pair> to be outright ill-formed.
With that issue's resolution, in cases where the constructor is not explicit we would create a temporary pair
and then do uses-allocator construction using its pieces, and it still won't work when the constructor is explicit.
We should just do this properly.
[2022-11-09 Tim updates wording following LWG review]
During review of this issue LWG noticed that neither the constructor nor the new overload should accept subrange.
remove_cv_t in the new paragraph is added for consistency with LWG 3677(i).
[Kona 2022-11-12; Set priority to 2]
[2023-01-11; LWG telecon]
Replace P with U in p17 and
set status to Tentatively Ready (poll result: 8/0/0).
[2023-02-13 Approved at February 2023 meeting in Issaquah. Status changed: Voting → WP.]
Proposed resolution:
This wording is relative to N4917 after the application of LWG 3677(i).
Edit 22.3.2 [pairs.pair] as indicated:
template<class U1, class U2> constexpr explicit(see below) pair(pair<U1, U2>& p); template<class U1, class U2> constexpr explicit(see below) pair(const pair<U1, U2>& p); template<class U1, class U2> constexpr explicit(see below) pair(pair<U1, U2>&& p); template<class U1, class U2> constexpr explicit(see below) pair(const pair<U1, U2>&& p); template<pair-like P> constexpr explicit(see below) pair(P&& p);-14- Let
-15- Constraints:FWD(u)bestatic_cast<decltype(u)>(u).
(15.?) — For the last overload,
remove_cvref_t<P>is not a specialization ofranges::subrange,(15.1) —
is_constructible_v<T1, decltype(get<0>(FWD(p)))>istrueand(15.2) —
is_constructible_v<T2, decltype(get<1>(FWD(p)))>istrue.-16- Effects: Initializes
firstwithget<0>(FWD(p))andsecondwithget<1>(FWD(p)).
Edit 20.2.2 [memory.syn], header <memory> synopsis, as indicated:
namespace std {
[…]
// 20.2.8.2 [allocator.uses.construction], uses-allocator construction
[…]
template<class T, class Alloc, class U, class V>
constexpr auto uses_allocator_construction_args(const Alloc& alloc,
pair<U, V>& pr) noexcept;
template<class T, class Alloc, class U, class V>
constexpr auto uses_allocator_construction_args(const Alloc& alloc,
const pair<U, V>& pr) noexcept;
template<class T, class Alloc, class U, class V>
constexpr auto uses_allocator_construction_args(const Alloc& alloc,
pair<U, V>&& pr) noexcept;
template<class T, class Alloc, class U, class V>
constexpr auto uses_allocator_construction_args(const Alloc& alloc,
const pair<U, V>&& pr) noexcept;
template<class T, class Alloc, pair-like P>
constexpr auto uses_allocator_construction_args(const Alloc& alloc, P&& p) noexcept;
template<class T, class Alloc, class U>
constexpr auto uses_allocator_construction_args(const Alloc& alloc, U&& u) noexcept;
[…]
}
Add the following to 20.2.8.2 [allocator.uses.construction]:
template<class T, class Alloc, pair-like P> constexpr auto uses_allocator_construction_args(const Alloc& alloc, P&& p) noexcept;-?- Constraints:
-?- Effects: Equivalent to:remove_cv_t<T>is a specialization ofpairandremove_cvref_t<P>is not a specialization ofranges::subrange.return uses_allocator_construction_args<T>(alloc, piecewise_construct, forward_as_tuple(get<0>(std::forward<P>(p))), forward_as_tuple(get<1>(std::forward<P>(p))));
Edit 20.2.8.2 [allocator.uses.construction] p17:
template<class T, class Alloc, class U> constexpr auto uses_allocator_construction_args(const Alloc& alloc, U&& u) noexcept;-16- Let
FUNbe the function template:template<class A, class B> void FUN(const pair<A, B>&);-17- Constraints:
remove_cv_t<T>is a specialization ofpair, and either:
(17.1) —
remove_cvref_t<U>is a specialization ofranges::subrange, or(17.2) —
Udoes not satisfypair-likeand the expressionFUN(u)is not well-formed when considered as an unevaluated operand..