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

### 3212. `tuple_element_t<1, const span<int, 42>>` is `const int`

Section: 99 [span.tuple] Status: Resolved Submitter: Tim Song Opened: 2019-05-31 Last modified: 2020-09-06

Priority: 2

View all issues with Resolved 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 N4810.

> 1. Modify 22.7.2 [span.syn], header `<span>` synopsis, as indicated:

>    >     […]
>    >     // 99 [span.tuple], tuple interface
>    >     template<class T> class tuple_size;
>    >     template<size_t I, class T> class tuple_element;
>    >     template<class ElementType, size_t Extent>
>    >       struct tuple_size<span<ElementType, Extent>>;
>    >     template<class ElementType>
>    >       struct tuple_size<span<ElementType, dynamic_extent>>; // not defined
>    >     template<size_t I, class ElementType, size_t Extent>
>    >       struct tuple_element<I, span<ElementType, Extent>>;
>    >     template<size_t I, class ElementType, size_t Extent>
>    >       struct tuple_element<I, const span<ElementType, Extent>>;
>    >     template<size_t I, class ElementType, size_t Extent>
>    >       struct tuple_element<I, volatile span<ElementType, Extent>>;
>    >     template<size_t I, class ElementType, size_t Extent>
>    >       struct tuple_element<I, const volatile span<ElementType, Extent>>;
>    >     […]

> 2. Modify 99 [span.tuple] before p1 as indicated:

>    > [Drafting note: The representation style for the newly added wording follows the new style for `tuple_element<I, span<ElementType, Extent>>::type`, which had recently been changed editorially.]

>    >     template<class ElementType, size_t Extent>
>    >       struct tuple_size<span<ElementType, Extent>>
>    >         : integral_constant<size_t, Extent> { };

>    >     tuple_element<I, span<ElementType, Extent>>::type

>    >     template<size_t I, class ElementType, size_t Extent>
>    >       struct tuple_element<I, const span<ElementType, Extent>> {
>    >         using type = ElementType;
>    >       };

>    >     template<size_t I, class ElementType, size_t Extent>
>    >       struct tuple_element<I, volatile span<ElementType, Extent>> {
>    >         using type = ElementType;
>    >       };

>    >     template<size_t I, class ElementType, size_t Extent>
>    >       struct tuple_element<I, const volatile span<ElementType, Extent>> {
>    >         using type = ElementType;
>    >       };

>    > > -1- Mandates: `Extent != dynamic_extent && I < Extent` is `true`.

[2020-02-13, Prague]

Wording needs to be adjusted, because we accepted P1831R1.

Previous resolution [SUPERSEDED]:

> This wording is relative to N4849.

> 1. Modify 22.7.2 [span.syn], header `<span>` synopsis, as indicated:

>    >     […]
>    >     // 99 [span.tuple], tuple interface
>    >     template<class T> class tuple_size;
>    >     template<size_t I, class T> class tuple_element;
>    >     template<class ElementType, size_t Extent>
>    >       struct tuple_size<span<ElementType, Extent>>;
>    >     template<class ElementType>
>    >       struct tuple_size<span<ElementType, dynamic_extent>>; // not defined
>    >     template<size_t I, class ElementType, size_t Extent>
>    >       struct tuple_element<I, span<ElementType, Extent>>;
>    >     template<size_t I, class ElementType, size_t Extent>
>    >       struct tuple_element<I, const span<ElementType, Extent>>;
>    >     […]

> 2. Modify 99 [span.tuple] before p1 as indicated:

>    >     template<class ElementType, size_t Extent>
>    >       struct tuple_size<span<ElementType, Extent>>
>    >         : integral_constant<size_t, Extent> { };

>    >     template<size_t I, class ElementType, size_t Extent>
>    >       struct tuple_element<I, span<ElementType, Extent>> {
>    >         using type = ElementType;
>    >       };

>    >     template<size_t I, class ElementType, size_t Extent>
>    >       struct tuple_element<I, const span<ElementType, Extent>> {
>    >         using type = ElementType;
>    >       };

>    > > -1- Mandates: `Extent != dynamic_extent && I < Extent` is `true`.

> 3. Add the following wording to Annex D:

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

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

>    > >     namespace std {
>    > >       template<size_t I, class ElementType, size_t Extent>
>    > >         struct tuple_element<I, volatile span<ElementType, Extent>>;
>    > >       template<size_t I, class ElementType, size_t Extent>
>    > >         struct tuple_element<I, const volatile span<ElementType, Extent>>;
>    > >     }

>    > D.1.? tuple interface [depr.span.tuple]

>    > >     template<size_t I, class ElementType, size_t Extent>
>    > >       struct tuple_element<I, volatile span<ElementType, Extent>> {
>    > >         using type = ElementType;
>    > >       };

>    > >     template<size_t I, class ElementType, size_t Extent>
>    > >       struct tuple_element<I, const volatile span<ElementType, Extent>> {
>    > >         using type = ElementType;
>    > >       };

>    > -?- Mandates: `Extent != dynamic_extent && I < Extent` is `true`.

[2020-02-14, Prague]

Lengthy discussion about the intended design of `span`'s tuple interface. Has been send to LEWG, who made several polls and concluded to remove the tuple interface for `span` for C++20.

Will be resolved by P2116R0.

[2020-05-01; reflector discussions]

Resolved by P2116R0 voted in in Prague.

Proposed resolution:

Resolved by P2116R0.