Ответ 1
Это похоже на недосмотр. Конструкторы массива в настоящее время определены как:
template<size_t N> constexpr span(array<value_type, N>& arr) noexcept;
template<size_t N> constexpr span(const array<value_type, N>& arr) noexcept;
Но, вероятно, следует указать как:
template<class T, size_t N>
requires std::convertible_to<T(*)[], ElementType(*)[]>
constexpr span(array<T, N>& arr) noexcept;
template<class T, size_t N>
requires std::convertible_to<const T(*)[], ElementType(*)[]>
constexpr span(const array<T, N>& arr) noexcept;
Что может привести к компиляции вашего примера, поскольку это безопасно. Я представил вопрос LWG. Теперь это LWG 3255.
В формулировке уже есть это ограничение, указанное в [span.cons]/11:
template<size_t N> constexpr span(element_type (&arr)[N]) noexcept; template<size_t N> constexpr span(array<value_type, N>& arr) noexcept; template<size_t N> constexpr span(const array<value_type, N>& arr) noexcept;
Constraints:
extent == dynamic_extent || N == extent
- этоtrue
, аremove_pointer_t<decltype(data(arr))>(*)[]
конвертируется вElementType(*)[]
.
Таким образом, у нас уже есть правильное ограничение. Просто data(arr)
на самом деле не зависит ни в одном из этих случаев, поэтому ограничение выполняется тривиально. Нам просто нужно сделать эти шаблоны.