猿问

此“数组大小”模板功能如何工作?

有人可以解释此代码的工作原理吗?我知道这段代码的目的是获取数组的长度,但是我不知道这段代码是如何工作的:


template<typename T, int size>

int GetArrLength(T(&)[size]){return size;}

谢谢。


慕码人2483693
浏览 513回答 3
3回答

慕娘9325324

首先让我们剖析参数T(&)[size]。首先从内到外,从右到左,从括号组中读取声明:这是一个未命名的参数,是size对type类型的数组的引用T。也就是说,它接受对任何数组的引用,其中数组的类型和大小是模板参数。如果我们这样称呼它:int a[10];GetArrLength(a);编译器将尝试推断模板参数。为了使参数类型与您要传递的参数相匹配,T必须为int并且size必须为10(使参数成为对10 ints 数组的引用)。然后,您返回该大小,从而获得数组中元素的数量。此代码有两个“问题”。首先,大小不能为负,因此使用带符号类型作为模板参数和返回类型没有意义。而是应使用无符号类型。最好是std::size_t:template<typename T, std::size_t Size>std::size_t GetArrLength(T(&)[Size]) { return size; }第二个问题是,即使数组的大小是多少,此函数的结果也不是常量表达式。虽然在大多数情况下都可以,但是如果我们可以从中获得一个常量表达式,那就更好了。那就是您得到此解决方案的地方:template <std::size_t N>struct type_of_size{&nbsp; &nbsp; 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!它通过三件事起作用:第一是与上面相同的想法,模板参数将被填充以提供数组的大小。第二部分是使用该信息来创建具有特定大小的类型,从而成为一个type_of_size辅助对象。该部分不是严格必需的,但我认为它使代码更易于阅读。A char[N]的大小N始终等于,因此我们可以滥用它来“存储”数组的大小……以类型本身的大小!第三部分是使用来获得该大小sizeof。它实际上不评估任何东西,因此我们不需要为函数定义。它只是说:“如果要这样做,大小将是……”。大小是char数组中“存储”的大小。

忽然笑

您可以牺牲可读性来跳过最后一个版本中的样板代码,但是我将其写为@Matthew Flaschen和@BobAlmond的练习:) template <typename T, size_t size> char (&sizeof_array_helper( T (&)[size]))[size];-宏将保留原样。

翻翻过去那场雪

使用C ++ 11时constexpr,“ return n;”&nbsp;函数成为编译时间常数!template <typename T, size_t n> constexpr size_t array_size(const T (&)[n]) { return n; }
随时随地看视频慕课网APP
我要回答