This page is a snapshot from the LWG issues list, see theLibrary Active Issues List for more information and the meaning ofWP status.
tuple can create dangling references fromtuple-likeSection: 22.4.4.2[tuple.cnstr]Status:WPSubmitter: Jonathan WakelyOpened: 2024-01-24Last modified: 2024-04-02
Priority:Not Prioritized
View otheractive issues in [tuple.cnstr].
View all otherissues in [tuple.cnstr].
View all issues withWP status.
Discussion:
P2165R4(Compatibility between tuple, pair and tuple-like objects)added two new constructors tostd::tuple:
template<tuple-likeUTuple> constexpr explicit(see below ) tuple(UTuple&& u);and the allocator-extended equivalent.Unlike the existing constructors taking a single parameter of tuple type,these new constructors are not defined as deleted if they would create adangling reference to a temporary. The existing constructors gained thatrestriction fromP2255R2(A type trait to detect reference binding to temporary)which was approved one meeting beforeP2165R4so LWG seem to have missed the inconsistency.
The proposal also added a new constructor forstd::pair:
template<pair-like P> constexpr explicit(see below) pair(P&& p);Thisis deleted if it would create a dangling reference,although that seems to be an almost accidental consequence of addingthe new signature after existing ones which already have theRemarks:about being deleted.
[2024-03-12; Reflector poll]
Set status to Tentatively Ready after eleven votes in favour during reflector poll.
[Tokyo 2024-03-23; Status changed: Voting → WP.]
Proposed resolution:
This wording is relative toN4971.
Modify 22.4.4.2[tuple.cnstr] as indicated:
template<tuple-like UTuple> constexpr explicit(see below) tuple(UTuple&& u);-28-Let
Ibe the pack0, 1, ..., (sizeof...(Types) - 1).-29-Constraints:
- (29.1) –
different-from<UTuple, tuple>(25.5.2[range.utility.helpers]) istrue,- (29.2) –
remove_cvref_t<UTuple>is not a specialization ofranges::subrange,- (29.3) –
sizeof...(Types)equalstuple_size_v<remove_cvref_t<UTuple>>,- (29.4) –
(is_constructible_v<Types, decltype(get<I>(std::forward<UTuple>(u)))> && ...)istrue, and- (29.5) –either
sizeof...(Types)is not 1,or (whenTypes...expands toT)is_convertible_v<UTuple, T>andis_constructible_v<T, UTuple>are bothfalse.-30-Effects:For alli,initializes theith element of
*thiswithget<i>(std::forward<UTuple>(u)).-31-Remarks:The expression inside
explicitis equivalent to:!(is_convertible_v<decltype(get<I>(std::forward<UTuple>(u))), Types> && ...)The constructor is defined as deleted if
(reference_constructs_from_temporary_v<Types, decltype(get<I>(std::forward<UTuple>(u)))> || ...)is
true.