std::extent 实现详细信息说明

std::extent implementation details explanation

本文关键字:说明 详细信息 extent std 实现      更新时间:2023-10-16
// basic template: covers non-array types
template<class T, unsigned N = 0>
struct extent : std::integral_constant<std::size_t, 0> {};
// 1st specialization: covers 1st dimension of array of uknown bound
template<class T>
struct extent<T[], 0> : std::integral_constant<std::size_t, 0> {};
// 2nd specialization: covers Nth dimension of array of uknown bound
template<class T, unsigned N>
struct extent<T[], N> : extent<T, N-1> {};
// 3rd  specialization: covers 1st dimension of array of known type
template<class T, std::size_t I>
struct extent<T[I], 0> : std::integral_constant<std::size_t, I> {};
// 4th  specialization: covers Nth dimension of array of known type
template<class T, std::size_t I, unsigned N>
struct extent<T[I], N> : extent<T, N-1> {};

可能从其他资源获取的实现。 可敬的社区可以解释一下这是如何工作的。看看第 4 个规范,不清楚<T[I]>,作为<T, N - 1>递归传递给基类,如何转换为继承上层数组的子数组类型。例如,如果我们调用extent< int[2][5], 1 >whereT[I] = int [2][5], N = 1然后我们传递给基类T, N - 1;基正在实例化,就好像我们传递int[2]一样,因为第一个(最派生的(T[I]被认为是两个int[5]的数组,所以基类中的Tint[5]I = 5的地方。这是对的吗?

接下来,为什么第二个规范(对于未知边界的数组(而不是使用零大小,作为第一个规范,依赖于递归实例化,就好像在维度的某个级别上可以知道大小一样。这个案例的背景是什么,你能举个例子吗?

可运行代码段: https://coliru.stacked-crooked.com/a/2150f81a547674e6

侧面:有人指出了有帮助 https://cppinsights.io/;还有Microsoft C++建立见解(对我不起作用(。

对于你的第一个问题:你是对的。

extent<int[2][5], 1>使用第 4 个专业化,导致

template<class T=int[5], std::size_t I=2, unsigned N=1>
struct extent<T[I], N> : extent<int[5], 0> {};

使用第三种专业化,导致

template<class T=int, std::size_t I=5>
struct extent<T[I], 0> : std::integral_constant<std::size_t, 5> {};

所以extent<int[2][5], 1>::value5.

关于问题2,让我们以extent<int[][5], 1>为例。它使用专用化 2 并导致

template<class T=int[5], unsigned N=1>
struct extent<T[], N> : extent<int[5], 0> {};

这使用第三个专业,而不是第一个专业!

template<class T=int, std::size_t I=5>
struct extent<T[I], 0> : std::integral_constant<std::size_t, 5> {};

在我看来,第一次过载是不必要的。Visual Studio 2019的STL省略了这个,只是回退到基本模板。

正如我之前在评论中写的那样,您也可以摆弄 https://cppinsights.io/。