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 23.7.2.1 [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 23.7.2.1 [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> (23.7.2.1 [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.