当前位置:  开发笔记 > 编程语言 > 正文

有人可以解释这个模板代码,它给我一个数组的大小?

如何解决《有人可以解释这个模板代码,它给我一个数组的大小?》经验,为你挑选了2个好方法。

好吧,首先你必须明白,试图从数组中获取一个值可以给你一个指向它的第一个元素的指针:

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

引用引用使用其确切类型或基类类型的对象.关键是模板通过引用获取数组.C++中不存在作为参数的数组(不是对它们的引用).如果为参数提供数组类型,则它将是指针.因此,当我们想知道传递的数组的大小时,使用引用是必要的.自动推导出大小和元素类型,通常是函数模板的情况.以下模板

template
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
char (& array_size(const T (&)[n]) )[n];

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

size_t size_of_a = sizeof(array_size(a));

因为char具有n元素的数组具有sizeof n,所以也将给出给定数组中元素的数量.在编译时,你可以做到

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

因为函数永远不会被实际调用,所以不需要定义它,因此它没有实体.希望我能稍微澄清一下这个问题.



1> Johannes Sch..:

好吧,首先你必须明白,试图从数组中获取一个值可以给你一个指向它的第一个元素的指针:

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

引用引用使用其确切类型或基类类型的对象.关键是模板通过引用获取数组.C++中不存在作为参数的数组(不是对它们的引用).如果为参数提供数组类型,则它将是指针.因此,当我们想知道传递的数组的大小时,使用引用是必要的.自动推导出大小和元素类型,通常是函数模板的情况.以下模板

template
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
char (& array_size(const T (&)[n]) )[n];

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

size_t size_of_a = sizeof(array_size(a));

因为char具有n元素的数组具有sizeof n,所以也将给出给定数组中元素的数量.在编译时,你可以做到

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

因为函数永远不会被实际调用,所以不需要定义它,因此它没有实体.希望我能稍微澄清一下这个问题.


使用C++ 11的`constexpr`,'return n;' 函数成为编译时常量!`template constexpr size_t array_size(const T(&)[n]){return n; }`

2> Eclipse..:

可以这样想,假设你有一堆功能:

// 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 
size_t array_size(const int (&)[n])
{
    return n;
}

编译器将尝试实例化array_size的一个版本,该版本匹配您调用它的任何参数.因此,如果使用10个int的数组调用它,它将实例化array_size,其中n = 10.

接下来,只是模板化类型,因此您可以使用不仅仅是int数组来调用它:

template 
size_t array_size(const T (&)[n])
{
    return n;
}

而且你已经完成了.

编辑:有关的说明(&)

需要括号&来区分int引用数组(非法)和引用int数组(你想要的).由于优先级[]高于&,如果你有声明:

const int &a[1];

由于运算符优先级,最终会得到一个对int引用的单元素数组.如果你想&先应用,你需要用括号强制它:

const int (&a)[1];  

现在你有了一个int元素数组的const引用.在函数参数列表中,如果不使用参数名称,则无需指定参数名称,因此可以删除名称,但保留括号:

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


在这两种情况下,您实际上都需要括号.
推荐阅读
手机用户2402852307
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有