【发布时间】:2020-05-19 12:31:40
【问题描述】:
漫步the code of libcxx's std::span,我注意到前两个值构造函数(cppreference 上的数字 2 和 3)不是模板。
_LIBCPP_INLINE_VISIBILITY constexpr span(pointer __ptr, index_type __count) : __data{__ptr}
{ (void)__count; _LIBCPP_ASSERT(_Extent == __count, "size mismatch in span's constructor (ptr, len)"); }
_LIBCPP_INLINE_VISIBILITY constexpr span(pointer __f, pointer __l) : __data{__f}
{ (void)__l; _LIBCPP_ASSERT(_Extent == distance(__f, __l), "size mismatch in span's constructor (ptr, ptr)"); }
它们直接使用 pointer 类型,而不是 cppreference 页面上显示的模板类型 It 和 End。所以我想知道 libcxx 代码是否符合要求。
我想要一个比较点,所以我继续查看the libstdc++ version,这个确实使用了模板(因此更长一些)。
template<contiguous_iterator _It>
requires __is_compatible_ref<iter_reference_t<_It>>::value
constexpr explicit(extent != dynamic_extent)
span(_It __first, size_type __count)
noexcept
: _M_extent(__count), _M_ptr(std::to_address(__first))
{
if constexpr (_Extent != dynamic_extent)
{
__glibcxx_assert(__count == _Extent);
}
}
template<contiguous_iterator _It, sized_sentinel_for<_It> _End>
requires __is_compatible_ref<iter_reference_t<_It>>::value
&& (!is_convertible_v<_End, size_type>)
constexpr explicit(extent != dynamic_extent)
span(_It __first, _End __last)
noexcept(noexcept(__last - __first))
: _M_extent(static_cast<size_type>(__last - __first)),
_M_ptr(std::to_address(__first))
{
if constexpr (_Extent != dynamic_extent)
{
__glibcxx_assert((__last - __first) == _Extent);
}
}
现在,在 cppreference 页面上,提到这两个构造函数仅在 It 满足 contiguous_iterator 并且从 std::iter_reference_t<It> 到 element_type 的转换最多时才参与重载解析资格转换。为了满足这一点,libstdc++ 代码使用 contiguous_iterator 概念作为模板类型名 (defined here) 和 __is_compatible_ref 要求 (defined just above)。
所以,这里是我的问题:是直接使用pointer类型,而不是混淆概念和要求,实际上符合标准吗? libcxx 代码是否正确,而 libstdc++ 代码是否过于复杂?
我还想将问题扩展到接下来的三个构造函数(处理原始数组和std::array,cppreference 上的数字 4、5 和 6)。
【问题讨论】:
-
您知道 C++20 目前正在开发中吗?比如p0122r5指定了libc++实现的构造函数(
constexpr span(pointer ptr, index_type count);),所以看起来libc++没有完全更新到最新的草稿版本。 -
libcxx 代码对我来说似乎不完整。
constexpr span(pointer __f, pointer __l)是不够的,例如,如果我将一对迭代器传递给一个向量。我想知道他们是否还没有完成实施。 -
@DanielLangr TBF,C++20 完成。 AFAIK 它只是通过最后的官僚和编辑步骤,所以现在什么都不会改变。
-
@NathanOliver 公平点。
-
标准可能已经完成,但实施仍在开发中,有些可能是从旧的不同版本开始的一段时间
标签: c++ language-lawyer std c++20