gpt4 book ai didi

c++ - 这个获取数组大小的模板代码是如何工作的?

转载 作者:行者123 更新时间:2023-12-01 22:05:35 35 4
gpt4 key购买 nike

我想知道为什么这样的代码可以获取测试数组的大小?我不熟悉模板中的语法。也许有人可以解释template<typename,size_t>下代码的含义。此外,最好有引用链接。

#define dimof(array) (sizeof(DimofSizeHelper(array)))
template <typename T, size_t N>
char(&DimofSizeHelper(T(&array)[N]))[N];

void InitDynCalls()
{
char test[20];
size_t n = dimof(test);
printf("%d", n);
}

最佳答案

这实际上是一个很难解释的问题,但我会尝试一下......

首先,dimof 告诉您维度,即数组中元素的数量。 (我相信“维度”是 Windows 编程环境中的首选术语)。

这是必要的,因为 C++C 没有为您提供确定数组大小的 native 方法。

<小时/>

人们通常认为 sizeof(myArray) 会起作用,但这实际上会给你内存中的大小,而不是元素的数量。每个元素可能占用超过 1 个字节的内存!

接下来,他们可能会尝试 sizeof(myArray)/sizeof(myArray[0])。这将给出数组内存中的大小除以第一个元素的大小。没关系,并且广泛用于 C 代码中。这样做的主要问题是,如果您传递指针而不是数组,它似乎可以工作。内存中指针的大小通常为 4 或 8 字节,即使它指向的内容可能是一个包含 1000 个元素的数组。

<小时/>

因此,在 C++ 中要尝试的下一件事是使用模板来强制某些仅适用于数组的内容,并且会在指针上给出编译器错误。它看起来像这样:

template <typename T, std::size_t N>
std::size_t ArraySize(T (&inputArray)[N])
{
return N;
}
//...
float x[7];
cout << ArraySize(x); // prints "7"

该模板仅适用于数组。它将推断出数组的类型(不是真正需要的,但必须存在才能使模板正常工作)和大小,然后返回大小。模板的编写方式不可能与指针一起使用。

通常你可以停在这里,这在 C++ 标准库中为 std::size .

<小时/>

警告:下面它进入了毛茸茸的语言律师领域。

<小时/>

这非常酷,但在模糊的边缘情况下仍然失败:

struct Placeholder {
static float x[8];
};

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

int main()
{
return ArraySize(Placeholder::x);
}

请注意,数组x声明,但未定义。要使用它调用函数(即 ArraySize),x must be defined .

In function `main':
SO.cpp:(.text+0x5): undefined reference to `Placeholder::x'
collect2: error: ld returned 1 exit status

您无法链接此内容。

<小时/>

问题中的代码是解决这个问题的方法。我们没有实际调用函数,而是声明一个返回大小正好合适的对象的函数。然后我们使用 sizeof 技巧。

看起来就像我们调用该函数,但sizeof纯粹是一个编译时构造,因此该函数实际上从未被调用。

template <typename T, size_t N>
char(&DimofSizeHelper(T(&array)[N]))[N];
^^^^ ^ ^^^
// a function that returns a reference to array of N chars - the size of this array in memory will be exactly N bytes

请注意,您实际上无法从函数返回数组,但可以返回对数组的引用。

DimofSizeHelper(myArray) 是一个 表达式,其 typeN char 上的数组 。该表达式实际上不必是可运行的,但它在编译时有意义。

因此,sizeof(DimofSizeHelper(myArray)) 会告诉您如果您实际调用该函数,您将得到的编译时大小。即使我们实际上并没有调用它。

Austin Powers Cross-Eyed

<小时/>

如果最后一个 block 没有任何意义,请不要担心。这是解决奇怪边缘情况的奇怪技巧。这就是为什么您不自己编写此类代码,并让库实现者担心此类废话。

关于c++ - 这个获取数组大小的模板代码是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58408024/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com