这实际上是一个很难解释的问题,但我会尝试一下...
首先,dimof
告诉您数组的维数或元素数。(我相信“维”是Windows编程环境中的首选术语)。
这是必要的,因为C++
并且C
没有给您提供确定数组大小的本地方法。
人们通常认为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
必须先定义。
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)
是一个表达式,其类型是N
char
s 上的数组。该表达式实际上不一定是可运行的,但在编译时是有意义的。
因此,sizeof(DimofSizeHelper(myArray))
它将告诉您在编译时实际调用该函数所得到的大小。即使我们实际上不称呼它。
不要担心最后一块没有任何意义。解决一个奇怪的边缘情况是一个奇怪的把戏。这就是为什么您不自己编写此类代码,而让库实现者担心此类废话的原因。
std::array
std::vector