在 C 中获取数组元素计数的常用方法如下:
#define COUNTOF(arr) (sizeof(arr) / sizeof(arr[0]))
这会产生一个积分常数表达式,这也是一个非常好的加分项。
问题是它不是类型安全的:int* i; COUNTOF(i); /* compiles :( */
. 在实践中,这应该很少出现,但为了正确起见,最好让这个类型安全。
在 C++03 中这很容易(在 C++11 中更容易,留给读者作为练习):
template <typename T, std::size_t N>
char (&countof_detail(T (&)[N]))[N]; // not defined
#define COUNTOF(arr) (sizeof(countof_detail(arr)))
这使用模板推导来获取N
数组的大小,然后将其编码为类型的大小。
但是在 C 中我们没有那种语言特性。这是我制作的小框架:
// if `condition` evaluates to 0, fails to compile; otherwise results in `value`
#define STATIC_ASSERT_EXPR(condition, value) \
(sizeof(char[(condition) ? 1 : -1]), (value))
// usual type-unsafe method
#define COUNTOF_DETAIL(arr) (sizeof(arr) / sizeof(arr[0]))
// new method:
#define COUNTOF(arr) \
STATIC_ASSERT_EXPR(/* ??? */, \
COUNTOF_DETAIL(arr)) \
我可以投入什么/* ??? */
来获得我想要的行为?或者这是不可能的?
我更喜欢 MSVC(即 C89)中的答案,但为了好奇,任何明确的答案都可以。