这似乎是一个疏忽。数组构造函数当前指定为:
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;
约束:
extent == dynamic_extent || N == extent
是true
, 并且
remove_pointer_t<decltype(data(arr))>(*)[]
可转换为ElementType(*)[]
。
所以我们已经有了正确的约束。只是data(arr)
在任何这些情况下实际上并不依赖,所以约束很容易满足。我们只需要制作这些模板。