C++ 这个“数组大小”模板函数是如何工作的?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3368883/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 12:41:41  来源:igfitidea点击:

How does this "size of array" template function work?

c++arraystemplatessizesizeof

提问by BobAlmond

Can someone explain how this code works? I know that the purpose of this code is to get the length of an array, but I don't know how this code works:

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

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

回答by GManNickG

First let's dissect the parameter, T(&)[size]. Read declarations from inside out, right to left, parenthesis group first: It's an unnamed parameter that is a reference to an array of size sizeof type T.

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

That is, it accepts a reference to any array, where the type and size of the array are template parameters.

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

If we call it as such:

如果我们这样称呼它:

int a[10];
GetArrLength(a);

The compiler will try to deduce the template parameters. For the parameter type to match what you're passing, Tmust be intand sizemust be 10 (making the parameter a reference to an array of 10 ints).

编译器将尝试推断模板参数。要使参数类型与您传递的内容相匹配,T必须intsize必须为 10(使参数成为对 10int秒数组的引用)。

You then return that size, giving you the number of elements in an array.

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



There are two "problems" with this code. Firstly, sizes cannot be negative, so it doesn't make sense to use a signed type as the template parameter and return type. Rather, an unsigned type should be used; best would be std::size_t:

这段代码有两个“问题”。首先,sizes 不能是负数,所以使用有符号类型作为模板参数和返回类型是没有意义的。相反,应该使用无符号类型;最好是std::size_t

template<typename T, std::size_t Size>
std::size_t GetArrLength(T(&)[Size]) { return size; }

The second is that the result of this function is not a constant-expression, even though an array's size is. While that's fine in most situations, it would be better if we could get a constant-expression from it. That's where you end up with this solution:

第二个是这个函数的结果不是一个常量表达式,即使数组的大小是。虽然在大多数情况下这很好,但如果我们能从中得到一个常量表达式会更好。这就是你最终得到这个解决方案的地方:

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))

This is used as such:

这是这样使用的:

int a[10];
const std::size_t n = sizeof_array(a); // constant-expression!

It works by three things: the first is the same idea as above, that template parameters will be filled out giving you the array's size.

它通过三件事起作用:第一件事与上面的想法相同,模板参数将被填写给你数组的大小。

The second part is using that information to make a type with a specific size, hence the type_of_sizehelper. That part isn't strictly necessary, but I think it makes the code easier to read. A char[N]has a size equal to N, always, hence we can abuse that to "store" the size of the array...in the size of a typeitself!

第二部分是使用该信息来制作具有特定大小的类型,因此是type_of_size助手。这部分不是绝对必要的,但我认为它使代码更易于阅读。Achar[N]的大小N总是等于,因此我们可以滥用它来“存储”数组的大小......以类型本身的大小!

The third part is getting that size with sizeof. It doesn't actually evaluate anything, so we don't need a definition for the function. It simply says "If you were to do this...the size would be...". And the size is our "stored" size, in the chararray.

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