如前所述,代码实际上计算出数组中元素的数量,而不是结构。我会在需要时明确写出 sizeof() 除法。如果我要让它成为一个函数,我想在它的定义中明确说明它需要一个数组。
template<typename T,int SIZE>
inline size_t array_size(const T (&array)[SIZE])
{
return SIZE;
}
上面类似于xtofl's,除了它防止传递指向它的指针(表示指向动态分配的数组)并错误地得到错误的答案。
编辑:根据JohnMcG 进行简化。
编辑:内联。
不幸的是,上面没有提供编译时答案(即使编译器确实内联并优化它以使其成为引擎盖下的常量),因此不能用作编译时常量表达式。即它不能用作声明静态数组的大小。在 C++0x 下,如果将关键字 inline 替换为 constexpr(constexpr 是隐式内联的),这个问题就会消失。
constexpr size_t array_size(const T (&array)[SIZE])
jwfearn's 解决方案适用于编译时,但涉及在新名称声明中有效地“保存”数组大小的 typedef。然后通过该新名称初始化一个常量来计算数组大小。在这种情况下,也可以从一开始就简单地将数组大小保存为常量。
Martin York's 发布的解决方案也可以在编译时工作,但涉及使用非标准的 typeof() 运算符。解决这个问题的方法是等待 C++0x 并使用 decltype (到那时我们实际上不需要它来解决这个问题,因为我们将有 constexpr )。另一种选择是使用 Boost.Typeof,在这种情况下我们将使用
#include <boost/typeof/typeof.hpp>
template<typename T>
struct ArraySize
{
private: static T x;
public: enum { size = sizeof(T)/sizeof(*x)};
};
template<typename T>
struct ArraySize<T*> {};
并通过书写使用
ArraySize<BOOST_TYPEOF(foo)>::size
其中 foo 是数组的名称。