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

4569. mdspan should Mandates the relationship between element_type and reference

Section: 23.7.3.6.1 [mdspan.mdspan.overview] Status: New Submitter: Hewill Kang Opened: 2026-04-12 Last modified: 2026-04-17

Priority: Not Prioritized

View other active issues in [mdspan.mdspan.overview].

View all other issues in [mdspan.mdspan.overview].

View all issues with New status.

Discussion:

For mdspan, user-defined accessor A must meet the requirements of [mdspan.accessor.reqmts]. Particularly, proxy references should model common_reference_with<A::reference&&, A::element_type&> to ensure that there is a relationship between these two types rather than arbitrary types.

Although mspan already requires that the template parameter AccessorPolicy shall meet the accessor policy requirements, compared to various details, such a sensible relationship between element_type and reference should be directly reflected in mdspan's Mandates to prevent users from using non-compliant accessors:

struct BadAccessor {
  using offset_policy = BadAccessor;
  using element_type = int;
  using reference    = void;
  using data_handle_type = element_type*;
  reference access(data_handle_type, size_t) const;
};

mdspan<int, dims<2>, layout_right, BadAccessor> m;
m[0, 1]; // not rejected in libstdc++, libc++ and MSVC-STL

It should be emphasized that we provided very similar wording in 25.8.3 [coro.generator.class] p1.

Proposed resolution:

This wording is relative to N5032.

  1. Modify 23.7.3.6.1 [mdspan.mdspan.overview] as indicated:

    namespace std {
      template<class ElementType, class Extents, class LayoutPolicy = layout_right,
               class AccessorPolicy = default_accessor<ElementType>>
      class mdspan {
      public:
        using extents_type = Extents;
        using layout_type = LayoutPolicy;
        using accessor_type = AccessorPolicy;
        using mapping_type = layout_type::template mapping<extents_type>;
        using element_type = ElementType;
        using value_type = remove_cv_t<element_type>;
        using index_type = extents_type::index_type;
        using size_type = extents_type::size_type;
        using rank_type = extents_type::rank_type;
        using data_handle_type = accessor_type::data_handle_type;
        using reference = accessor_type::reference;
        […]
      };
      […]
    }
    

    -2- Mandates:

    1. (2.1) — ElementType is a complete object type that is neither an abstract class type nor an array type,

    2. (2.2) — Extents is a specialization of extents, and

    3. (2.3) — is_same_v<ElementType, typename AccessorPolicy::element_type> is true, and.

    4. (2.?) — common_reference_with<reference&&, element_type&> is modeled.