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.
std::mdspan taking (data_handle_type, mapping_type, accessor_type)
and the corresponding constructorSection: 23.7.3.6.1 [mdspan.mdspan.overview] Status: New Submitter: Jiang An Opened: 2026-01-09 Last modified: 2026-01-18
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:
Currently, the following deduction guide of std::mdspan takes the data handle by reference:
template<class MappingType, class AccessorType>
mdspan(const typename AccessorType::data_handle_type&, const MappingType&,
const AccessorType&)
-> mdspan<typename AccessorType::element_type, typename MappingType::extents_type,
typename MappingType::layout_type, AccessorType>;
But the corresponding constructor takes the data handle by value:
constexpr mdspan(data_handle_type p, const mapping_type& m, const accessor_type& a);
The distinction is observable with volatile glvalues. E.g., in the following example,
CTAD fails but explicitly specifying template arguments works
(demo):
#include <cstddef>
#include <mdspan>
int main() {
int a[1]{};
int * volatile p = a;
std::mdspan(
p,
std::layout_right::mapping<std::extents<std::size_t, 1>>{},
std::default_accessor<int>{}); // error (but accidentally accepted by libc++)
std::mdspan<int, std::extents<std::size_t, 1>>(
p,
std::layout_left::mapping<std::extents<std::size_t, 1>>{},
std::default_accessor<int>{}); // OK
}
Given we're generally passing data handle by value, it seems better to remove const & from
const typename AccessorType::data_handle_type& in the deduction guide, which is more
consistent with the constructor and accept more seemingly valid uses.
&,
see llvm/llvm-project#175024.
Proposed resolution:
This wording is relative to N5032.
Modify 23.7.3.6.1 [mdspan.mdspan.overview], class template mdspan synopsis, as indicated:
namespace std {
[…]
template<class MappingType, class AccessorType>
mdspan(const typename AccessorType::data_handle_type&, const MappingType&,
const AccessorType&)
-> mdspan<typename AccessorType::element_type, typename MappingType::extents_type,
typename MappingType::layout_type, AccessorType>;
}