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

有人能解释给我数组大小的模板代码吗?

有人能解释给我数组大小的模板代码吗?

C++
白板的微信 2019-07-03 15:59:41
有人能解释给我数组大小的模板代码吗?template<typename T, size_t n>size_t array_size(const T (&)[n]){     return n;}我没有得到的部分是这个模板函数的参数。当我将数组传递给n数组中元素的数量?
查看完整描述

3 回答

?
慕容森

TA贡献1853条经验 获得超18个赞

首先,您必须理解,尝试从数组中获取值可以为您提供指向其第一个元素的指针:

int a[] = {1, 2, 3};int *ap = a; // a pointer, size is lostint (&ar)[3] = a; // a reference to the array, size is not lost

引用是指使用对象的确切类型或基类类型的对象。关键是模板通过引用接收数组。数组(而不是对它们的引用)作为参数在C+中不存在。如果您给一个参数一个数组类型,它将是一个指针。因此,当我们想知道传递数组的大小时,使用引用是必要的。大小和元素类型是自动推导出来的,就像函数模板的一般情况一样。以下模板

template<typename T, size_t n>size_t array_size(const T (&)[n]) {
    return n;}

使用我们先前定义的数组调用a将隐式实例化以下函数:

size_t array_size(const int (&)[3]) {
    return 3;}

可以这样使用:

size_t size_of_a = array_size(a);

一段时间前我编造了一个变体编辑:原来有人已经有了同样的想法这里]它可以在编译时确定一个值。它没有直接返回值,而是根据n:

template<typename T, size_t n>char (& array_size(const T (&)[n]) )[n];

你说如果数组n元素时,返回类型是对具有大小的数组的引用。n元素类型char..现在,您可以获得已传递数组的编译时确定的大小:

size_t size_of_a = sizeof(array_size(a));

因为一个数组charn元素有相当大的n,这也会给出给定数组中元素的数量。在编译时,所以您可以

int havingSameSize[sizeof(array_size(a))];

因为函数从来没有被真正调用过,所以它不需要被定义,所以它没有一个身体。希望我能把这件事弄清楚一点。


查看完整回答
反对 回复 2019-07-03
?
开心每一天1111

TA贡献1836条经验 获得超13个赞

可以这样想,假设您有一堆函数:

// Note that you don't need to name the array, since you don't// actually reference the parameter at all.size_t array_size(const int (&)[1]){
    return 1;}size_t array_size(const int (&)[2]){
    return 2;}size_t array_size(const int (&)[3]){
    return 3;}// etc...

现在,当您调用这个函数时,哪个函数会被调用?

int a[2];array_size(a);

现在,如果您将数组大小临时化,您将得到:

template <int n>size_t array_size(const int (&)[n]){
    return n;}

编译器将尝试实例化与调用它的任何参数匹配的数组_size版本。因此,如果您用一个10 int的数组调用它,它将用n=10实例化arraysize。

接下来,只需将类型临时化,这样您就可以使用多个int数组来调用它了:

template <typename T, int n>size_t array_size(const T (&)[n]){
    return n;}

你就完蛋了。

编辑*关于(&)

控件周围需要括号。&若要区分int引用数组(非法)和INT数组(您想要什么),请执行以下操作。因为.的优先[]高于&,如果你有以下声明:

const int &a[1];

由于运算符优先,您将得到一个对int的const引用的单元素数组。如果你想&首先,您需要强制使用括号:

const int (&a)[1];

现在,您有一个对一个元素数组的INT的Const引用。在函数参数列表中,如果不使用参数,则不需要指定参数的名称,因此可以删除名称,但保留括号:

size_t array_size(const int (&)[1])


查看完整回答
反对 回复 2019-07-03
?
忽然笑

TA贡献1806条经验 获得超5个赞

数组没有发生任何变化。它是一个未使用的参数,用于解析模板函数的签名。

它也不能用作模板参数,但这是一个单独的nit。


查看完整回答
反对 回复 2019-07-03
  • 3 回答
  • 0 关注
  • 419 浏览

添加回答

举报

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