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

### 3398. `tuple_element_t` is also wrong for `const subrange`

Section: 26.2 [ranges.syn] Status: C++20 Submitter: Casey Carter Opened: 2019-02-13 Last modified: 2021-02-25

Priority: 0

View other active issues in [ranges.syn].

View all other issues in [ranges.syn].

View all issues with C++20 status.

Discussion:

As currently specified, it uses the cv-qualified partial specialization, which incorrectly adds cv-qualification to the element type.

Previous resolution [SUPERSEDED]:

> This wording is relative to N4849.

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

>    >     […]
>    >     namespace std {
>    >       namespace views = ranges::views;

>    >       template<class I, class S, ranges::subrange_kind K>
>    >       struct tuple_size<ranges::subrange<I, S, K>>
>    >         : integral_constant<size_t, 2> {};
>    >       template<class I, class S, ranges::subrange_kind K>
>    >       struct tuple_element<0, ranges::subrange<I, S, K>> {
>    >         using type = I;
>    >       };
>    >       template<class I, class S, ranges::subrange_kind K>
>    >       struct tuple_element<1, ranges::subrange<I, S, K>> {
>    >         using type = S;
>    >       };
>    >       template<class I, class S, ranges::subrange_kind K>
>    >       struct tuple_element<0, const ranges::subrange<I, S, K>> {
>    >         using type = I;
>    >       };
>    >       template<class I, class S, ranges::subrange_kind K>
>    >       struct tuple_element<1, const ranges::subrange<I, S, K>> {
>    >         using type = S;
>    >       };
>    >     }

> 2. Add the following wording to Annex D:

>    > D.? Deprecated `subrange` tuple interface [depr.ranges.syn]

>    > 1 The header `<ranges>` (26.2 [ranges.syn]) has the following additions:

>    > >     namespace std {
>    > >       template<size_t X, class I, class S, ranges::subrange_kind K>
>    > >       struct tuple_element<X, volatile ranges::subrange<I, S, K>> {};
>    > >       template<size_t X, class I, class S, ranges::subrange_kind K>
>    > >       struct tuple_element<X, const volatile ranges::subrange<I, S, K>> {};
>    > >     }

[2020-02-14, Prague]

LWG decided to remove the volatile support, we shouldn't give the impression to support an idiom that wouldn't work.

Proposed resolution:

This wording is relative to N4849.

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

   >     […]
   >     namespace std {
   >       namespace views = ranges::views;

   >       template<class I, class S, ranges::subrange_kind K>
   >       struct tuple_size<ranges::subrange<I, S, K>>
   >         : integral_constant<size_t, 2> {};
   >       template<class I, class S, ranges::subrange_kind K>
   >       struct tuple_element<0, ranges::subrange<I, S, K>> {
   >         using type = I;
   >       };
   >       template<class I, class S, ranges::subrange_kind K>
   >       struct tuple_element<1, ranges::subrange<I, S, K>> {
   >         using type = S;
   >       };
   >       template<class I, class S, ranges::subrange_kind K>
   >       struct tuple_element<0, const ranges::subrange<I, S, K>> {
   >         using type = I;
   >       };
   >       template<class I, class S, ranges::subrange_kind K>
   >       struct tuple_element<1, const ranges::subrange<I, S, K>> {
   >         using type = S;
   >       };
   >     }