【问题标题】:Why are span's array and std::array constructors different from its container constructors为什么 span 的数组和 std::array 构造函数与其容器构造函数不同
【发布时间】:2019-12-18 00:42:47
【问题描述】:

我一直在研究 std::span 的最新规范,在 Godbolt 上使用 clang trunk 和 libc++,发现一些构造函数令人困惑。

特别是我发现来自普通旧数组和std::array 的构造函数与其他容器不同。

例如以下代码似乎可以编译:

std::vector<int*> v = {nullptr, nullptr};
std::span<const int* const> s{v};

但事实并非如此:

std::array<int*, 2> a = {nullptr, nullptr}; 
std::span<const int* const> s{a};

这似乎与the way the constructors are described on cppreference.com 一致,我只是在努力理解为什么会这样。有人能解释一下吗?

【问题讨论】:

    标签: c++ c++20 std-span


    【解决方案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;
    

    约束

    • extent == dynamic_­extent || N == extenttrue,并且
    • remove_­pointer_­t&lt;decltype(data(arr))&gt;(*)[] 可转换为 ElementType(*)[]

    所以我们已经有了正确的约束。只是data(arr) 在任何这些情况下实际上并不依赖,所以约束很容易满足。我们只需要制作这些模板。

    【讨论】:

    • 令人惊讶的是,文档确实说明了这一点:“这些重载仅在 extent == std::dynamic_extent || N == extent 为真 且 std::remove_pointer_t 时才参与重载决议(*)[] 可转换为 element_type (*)[]"
    • @Timo 哦,奇怪。是的,我们确实有这样的措辞......除了数组的底层类型不是模板......
    • 这正是我感到困惑的地方,尤其是对于普通旧数组的 element_type 和数组的 value_type 的具体选择。为什么它们会有所不同?
    猜你喜欢
    • 2016-05-31
    • 2014-05-02
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-28
    • 2017-04-11
    相关资源
    最近更新 更多