Title
`mdspan` constructor should disallow derived to base conversions
Status
new
Section
[mdspan.mdspan.cons]
Submitter
Hewill Kang

Created on 2025-10-05.00:00:00 last changed 2 days ago

Messages

Date: 2025-10-10.11:27:48

Proposed resolution:

This wording is relative to N5014.

[Drafting note: The exposition-only concept convertible-to-non-slicing comes from [range.subrange.general].]

  1. Modify [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 = typename layout_type::template mapping<extents_type>;
        using element_type = ElementType;
        using value_type = remove_cv_t<element_type>;
        using index_type = typename extents_type::index_type;
        using size_type = typename extents_type::size_type;
        using rank_type = typename extents_type::rank_type;
        using data_handle_type = typename accessor_type::data_handle_type;
        using reference = typename accessor_type::reference;
        […]
        template<class... OtherIndexTypes>
          constexpr explicit mdspan(convertible-to-non-slicing<data_handle_type> auto ptr, OtherIndexTypes... exts);
        template<class OtherIndexType, size_t N>
          constexpr explicit(N != rank_dynamic())
            mdspan(convertible-to-non-slicing<data_handle_type> auto p, span<OtherIndexType, N> exts);
        template<class OtherIndexType, size_t N>
          constexpr explicit(N != rank_dynamic())
            mdspan(convertible-to-non-slicing<data_handle_type> auto p, const array<OtherIndexType, N>& exts);
        constexpr mdspan(convertible-to-non-slicing<data_handle_type> auto p, const extents_type& ext);
        constexpr mdspan(convertible-to-non-slicing<data_handle_type> auto p, const mapping_type& m);
        constexpr mdspan(convertible-to-non-slicing<data_handle_type> auto p, const mapping_type& m, const accessor_type& a);
        […]
      };
      […]
    }
    
  2. Modify [mdspan.mdspan.cons] as indicated:

    template<class... OtherIndexTypes>
      constexpr explicit mdspan(convertible-to-non-slicing<data_handle_type> auto p, OtherIndexTypes... exts);
    

    -4- Let `N` be `sizeof...(OtherIndexTypes)`.

    -5- Constraints: […]

    […]

    template<class OtherIndexType, size_t N>
      constexpr explicit(N != rank_dynamic())
        mdspan(convertible-to-non-slicing<data_handle_type> auto p, span<OtherIndexType, N> exts);
    template<class OtherIndexType, size_t N>
      constexpr explicit(N != rank_dynamic())
        mdspan(convertible-to-non-slicing<data_handle_type> auto p, const array<OtherIndexType, N>& exts);
    

    -8- Constraints: […]

    […]

    constexpr mdspan(convertible-to-non-slicing<data_handle_type> auto p, const extents_type& ext);
    

    -11- Constraints: […]

    […]

    constexpr mdspan(convertible-to-non-slicing<data_handle_type> auto p, const mapping_type& m);
    

    -14- Constraints: […]

    […]

    constexpr mdspan(convertible-to-non-slicing<data_handle_type> auto p, const mapping_type& m, const accessor_type& a);
    

    -17- Preconditions: […]

    […]

Date: 2025-10-05.00:00:00

Unlike `ranges::subrange` or `span`, `mdspan` syntactically allows a multidimensional viewing base class via a derived class pointer (demo):

#include <span>
#include <ranges>
#include <mdspan>

struct Base {};
struct Derived : Base {};
std::array<Derived, 12> arr;
std::ranges::subrange<Base*> s(arr); // error, slicing
std::span<Base> sp(arr.data(), arr.size()); // error, slicing
std::mdspan<Base, std::dims<1>> msp(arr.data(), arr.size()); // ok

Given that we intend to reject object slicing for both `default_accessor` and `aligned_accessor`, there seems no reason not to reject this invalid pointer arithmetic for `mdspan`.

History
Date User Action Args
2025-10-10 11:27:48adminsetmessages: + msg15131
2025-10-05 00:00:00admincreate