mdspan::operator[]
should not copy OtherIndexTypes
Section: 23.7.3.6.3 [mdspan.mdspan.members] Status: WP Submitter: Casey Carter Opened: 2023-08-12 Last modified: 2023-11-22
Priority: Not Prioritized
View all issues with WP status.
Discussion:
The wording for mdspan
's operator[]
overloads that accept span
and array
is in
23.7.3.6.3 [mdspan.mdspan.members] paragraphs 5 and 6:
template<class OtherIndexType> constexpr reference operator[](span<OtherIndexType, rank()> indices) const; template<class OtherIndexType> constexpr reference operator[](const array<OtherIndexType, rank()>& indices) const;-5- Constraints:
(5.1) —
is_convertible_v<const OtherIndexType&, index_type>
istrue
, and(5.2) —
is_nothrow_constructible_v<index_type, const OtherIndexType&>
istrue
.-6- Effects: Let
P
be a parameter pack such thatis_same_v<make_index_sequence<rank()>, index_sequence<P...>>is
true
. Equivalent to:return operator[](as_const(indices[P])...);
The equivalent code calls the other operator[]
overload:
template<class... OtherIndexTypes> constexpr reference operator[](OtherIndexTypes... indices) const;
with a pack of const OtherIndexType
lvalues, but we notably haven't required OtherIndexTypes
to be copyable —
we only require that we can convert them to index_type
. While one could argue that the use in "Effects: equivalent to"
implies a requirement of copyability, it's odd that this implicit requirement would be the only requirement for copyable
OtherIndexTypes
in the spec. We could fix this by changing the operator[]
overload accepting OtherIndexTypes
to take them by const&
, but that would be inconsistent with virtually every other place in the spec where types
convertible to index_type
are taken by-value. I think the best localized fix is to perform the conversion to index_type
in the "Effects: equivalent to" code so the actual arguments have type index_type
which we know is copyable.
[2023-11-02; Reflector poll]
Set status to Tentatively Ready after eight votes in favour during reflector poll.
[2023-11-11 Approved at November 2023 meeting in Kona. Status changed: Voting → WP.]
Proposed resolution:
This wording is relative to N4958.
Modify 23.7.3.6.3 [mdspan.mdspan.members] as indicated:
template<class OtherIndexType> constexpr reference operator[](span<OtherIndexType, rank()> indices) const; template<class OtherIndexType> constexpr reference operator[](const array<OtherIndexType, rank()>& indices) const;-5- Constraints:
(5.1) —
is_convertible_v<const OtherIndexType&, index_type>
istrue
, and(5.2) —
is_nothrow_constructible_v<index_type, const OtherIndexType&>
istrue
.-6- Effects: Let
P
be a parameter pack such thatis_same_v<make_index_sequence<rank()>, index_sequence<P...>>is
true
. Equivalent to:return operator[](extents_type::index-cast(as_const(indices[P]))...);