*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.*

`mdspan::operator[]`

should not copy `OtherIndexTypes`

**Section:** 24.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
24.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>`

is`true`

, and(5.2) —

`is_nothrow_constructible_v<index_type, const OtherIndexType&>`

is`true`

.-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 24.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>`

is`true`

, and(5.2) —

`is_nothrow_constructible_v<index_type, const OtherIndexType&>`

is`true`

.

-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]))...);