This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of WP status.

### 3551. `borrowed_{iterator,subrange}_t` are overspecified

Section: 26.5.5 [range.dangling] Status: WP Submitter: Tim Song Opened: 2021-05-12 Last modified: 2021-06-07

Priority: Not Prioritized

View all issues with WP status.

Discussion:

As discussed in P1715R0, there are ways to implement something equivalent to `std::conditional_t` that are better for compile times. However, `borrowed_{iterator,subrange}_t` are currently specified to use `conditional_t`, and this appears to be user-observable due to the transparency of alias templates. We should simply specify the desired result and leave the actual definition to the implementation.

[2021-05-20; Reflector poll]

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

[2021-06-07 Approved at June 2021 virtual plenary. Status changed: Voting → WP.]

Proposed resolution:

This wording is relative to N4885.

1. Modify 26.2 [ranges.syn], header `<ranges>` synopsis, as indicated:

   >       […]
   >     namespace std::ranges {
   >       […]
   >       // 26.5.5 [range.dangling], dangling iterator handling
   >       struct dangling;

   >       template<range R>
   >         using borrowed_iterator_t = see belowconditional_t<borrowed_range<R>, iterator_t<R>, dangling>;

   >       template<range R>
   >         using borrowed_subrange_t = see below
   >           conditional_t<borrowed_range<R>, subrange<iterator_t<R>>, dangling>;

   >       […]
   >     }

2. Modify 26.5.5 [range.dangling] as indicated:

   > -1- The tag type `dangling` is used together with the template aliases `borrowed_iterator_t` and `borrowed_subrange_t`. When an algorithm that typically returns an iterator into, or a subrange of, a range argument is called with an rvalue range argument that does not model `borrowed_range` (26.4.2 [range.range]), the return value possibly refers to a range whose lifetime has ended. In such cases, the tag type `dangling` is returned instead of an iterator or subrange.

   > >     namespace std::ranges {
   > >       struct dangling {
   > >         […]
   > >       };
   > >     }

   > -2- [Example 1: […] — end example]

   > -?- For a type `R` that models `range`:

   > 1. (?.1) — if `R` models `borrowed_range`, then `borrowed_iterator_t<R>` denotes `iterator_t<R>`, and `borrowed_subrange_t<R>` denotes `subrange<iterator_t<R>>`;

   > 2. (?.2) — otherwise, both `borrowed_iterator_t<R>` and `borrowed_subrange_t<R>` denote `dangling`.