提问人:cbhattac 提问时间:6/14/2023 更新时间:6/14/2023 访问量:105
为什么 C++ span 的 C 样式数组构造函数需要type_identity_t?
Why does C++ span's C style array constructor need type_identity_t?
问:
span 的 C 样式数组构造函数指定如下
template<size_t N> constexpr span(
type_identity_t<element_type> (&arr)[N]) noexcept;
为什么有必要?而不仅仅是:type_identity_t
template<size_t N> constexpr span(
element_type (&arr)[N]) noexcept;
正如本提案中最初定义的那样?
答:
1赞
Yakk - Adam Nevraumont
#1
正如 cbhattac 的回答所解释的那样,问题在于 span 的推导指南选择了错误的超载。
在 issue3369 中,开发了一个修复程序。
核心问题是:
template <size_t Size>
requires (Extent == dynamic_extent || Extent == Size)
span(T (&)[Size]) {}
CTOR 生成隐式演绎指南,也是如此
template <typename T, size_t Extent>
span(T (&)[Extent]) -> span<T, Extent>;
构造函数构建一个具有可变长度的构造函数,而推导指南构建一个具有固定长度的构造函数。span
当传递一个固定长度的数组时,理想的推导跨度也应该是固定长度的。但这并没有发生。
天真地,显式演绎公会击败了构造函数生成的公会,但事实并非如此——由于子句,这里的构造函数受到的约束更大。所以它击败了扣除指南。requires (Extent == dynamic_extent || Extent == Size)
为了解决这个问题,用于完全阻止此构造函数的CTAD。(另一种可行的方法是在扣除指南中添加一个微不足道的约束)。type_identity_t<T>
评论