Title
tuple can create dangling references from tuple-like
Status
wp
Section
[tuple.cnstr]
Submitter
Jonathan Wakely

Created on 2024-01-24.00:00:00 last changed 8 months ago

Messages

Date: 2024-04-02.10:29:12

Proposed resolution:

This wording is relative to N4971.

  1. Modify [tuple.cnstr] as indicated:

    
    template<tuple-like UTuple>
      constexpr explicit(see below) tuple(UTuple&& u);
    

    -28- Let I be the pack 0, 1, ..., (sizeof...(Types) - 1).

    -29- Constraints:

    1. (29.1) – different-from<UTuple, tuple> ([range.utility.helpers]) is true,
    2. (29.2) – remove_cvref_t<UTuple> is not a specialization of ranges::subrange,
    3. (29.3) – sizeof...(Types) equals tuple_size_v<remove_cvref_t<UTuple>>,
    4. (29.4) – (is_constructible_v<Types, decltype(get<I>(std::forward<UTuple>(u)))> && ...) is true, and
    5. (29.5) – either sizeof...(Types) is not 1, or (when Types... expands to T) is_convertible_v<UTuple, T> and is_constructible_v<T, UTuple> are both false.

    -30- Effects: For all i, initializes the ith element of *this with get<i>(std::forward<UTuple>(u)).

    -31- Remarks: The expression inside explicit is 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.

Date: 2024-04-02.10:29:12

[ Tokyo 2024-03-23; Status changed: Voting → WP. ]

Date: 2024-03-15.00:00:00

[ 2024-03-12; Reflector poll ]

Set status to Tentatively Ready after eleven votes in favour during reflector poll.

Date: 2024-01-24.00:00:00

P2165R4 (Compatibility between tuple, pair and tuple-like objects) added two new constructors to std::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 a dangling reference to a temporary. The existing constructors gained that restriction from P2255R2 (A type trait to detect reference binding to temporary) which was approved one meeting before P2165R4 so LWG seem to have missed the inconsistency.

The proposal also added a new constructor for std::pair:


  template<pair-like P> constexpr explicit(see below) pair(P&& p);

This is deleted if it would create a dangling reference, although that seems to be an almost accidental consequence of adding the new signature after existing ones which already have the Remarks: about being deleted.

History
Date User Action Args
2024-04-02 10:29:12adminsetmessages: + msg14048
2024-04-02 10:29:12adminsetstatus: voting -> wp
2024-03-18 09:32:04adminsetstatus: ready -> voting
2024-03-12 00:52:24adminsetmessages: + msg13993
2024-03-12 00:52:24adminsetstatus: new -> ready
2024-01-24 21:12:14adminsetmessages: + msg13933
2024-01-24 00:00:00admincreate