为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C++
三国纷争 2019-12-13 11:10:59
有人可以解释此代码的工作原理吗?我知道这段代码的目的是获取数组的长度,但是我不知道这段代码是如何工作的:template<typename T, int size>int GetArrLength(T(&)[size]){return size;}谢谢。
查看完整描述

3 回答

?
Smart猫小萌

TA贡献1911条经验 获得超7个赞

首先让我们剖析参数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

{

    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数组中“存储”的大小。



查看完整回答
反对 回复 2019-12-14
?
大话西游666

TA贡献1817条经验 获得超14个赞

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


查看完整回答
反对 回复 2019-12-14
?
MM们

TA贡献1886条经验 获得超2个赞

使用C ++ 11时constexpr,“ return n;” 函数成为编译时间常数!template <typename T, size_t n> constexpr size_t array_size(const T (&)[n]) { return n; }

查看完整回答
反对 回复 2019-12-14
  • 3 回答
  • 0 关注
  • 323 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信