这个“数组大小”模板函数是如何工作的?

可能重复:
有人可以解释这个模板代码,给我一个数组的大小?
函数模板中的魔法参数

有人可以解释这个代码如何工作? 我知道这段代码的目的是获得一个数组的长度,但我不知道这个代码如何工作:

template<typename T, int size> int GetArrLength(T(&)[size]){return size;} 

谢谢。

首先让我们剖析参数T(&)[size] 。 首先从内向外读取声明,从右到左,括号组:这是一个未命名的参数,是对Tsize数组的引用。

也就是说,它接受对任何数组的引用,其中数组的types和大小是模板参数。

如果我们这样称呼它:

 int a[10]; GetArrLength(a); 

编译器将尝试推导出模板参数。 对于要传递的参数types, T必须是intsize必须是10(使参数成为10个int数组的引用)。

然后返回该大小,给出数组中元素的数量。


这个代码有两个“问题”。 首先,大小不能是负数,所以使用带符号types作为模板参数和返回types是没有意义的。 相反,应使用无符号types; 最好是std::size_t

 template<typename T, std::size_t Size> std::size_t GetArrLength(T(&)[Size]) { return size; } 

第二个是这个函数的结果不是一个常量expression式,即使数组的大小是。 虽然在大多数情况下都是好的,但如果我们能从中得到一个常数expression式,那将会更好。 这就是你最终得到这个解决scheme的地方:

 template <std::size_t N> struct type_of_size { typedef char type[N]; }; template <typename T, std::size_t Size> typename type_of_size<Size>::type& sizeof_array_helper(T(&)[Size]); #define sizeof_array(pArray) sizeof(sizeof_array_helper(pArray)) 

这是这样使用的:

 int a[10]; const std::size_t n = sizeof_array(a); // constant-expression! 

它的工作原理有三点:第一个是和上面相同的想法,模板参数将被填充,给你数组的大小。

第二部分是使用这些信息来创build一个具有特定大小的types,因此是type_of_size助手。 这部分并不是绝对必要的,但我认为它使代码更易于阅读。 一个char[N]的大小总是等于N ,因此我们可以滥用它来“存储”数组的大小……以一种types本身的大小!

第三部分是sizeof 。 它并不实际评估任何东西,所以我们不需要定义这个函数。 它只是说“如果你这样做……大小将是…”。 大小是我们的“存储”大小,在char数组中。