c++ - 这个 "size of array"模板函数是如何工作的?

标签 c++ arrays templates size sizeof

有人能解释一下这段代码是如何工作的吗?我知道这段代码的目的是获取数组的长度,但是不知道这段代码是怎么工作的:

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

最佳答案

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

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

如果我们这样调用它:

int a[10];
GetArrLength(a);

编译器会尝试推断模板参数。为了使参数类型与您传递的内容相匹配,T 必须是 int 并且 size 必须是 10(使参数成为对10 个 ints) 的数组。

然后您返回该大小,为您提供数组中元素的数量。


这段代码有两个“问题”。首先,sizes 不能为负数,因此使用有符号类型作为模板参数和返回类型是没有意义的。相反,应该使用无符号类型;最好是 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 帮助器。这部分不是绝对必要的,但我认为它使代码更易于阅读。 char[N] 的大小总是等于 N,因此我们可以滥用它来“存储”数组的大小...... 输入本身!

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

关于c++ - 这个 "size of array"模板函数是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3368883/

相关文章:

c++ - 类模板部分特化问题

c++ - Visual Studio 2012 Boost.Python 集成

c++ - 鼠标在代码中断时消失

Javascript : Sort array of object programmatically

java - 获取 ArrayIndexOutOfBoundsException,数组大小是动态确定的

python - 在这段代码中是否有任何 numpy 技巧可以避免 for 循环?

c++ - C++11 是否需要将此 lambda 声明为可变?

c++ - 拖放像 photoshop 这样的工具箱

templates - 我怎样才能让免费的 Pascal 编译器 xcode 模板与 xcode 4 一起工作

c++ - 使用 SFINAE 检查模板参数继承