先请各位看看代码,思考一下,这里的代码是做什么的?
template <typename T, size_t N>
char (&ArraySizeHelper(T (&array)[N]))[N];//没有定义,只做了声明
// That gcc wants both of these prototypes seems mysterious. VC, for
// its part, can't decide which to use (another mystery). Matching of
// template overloads: the final frontier.
#ifndef _MSC_VER
template 
<typename T, size_t N>
char (&ArraySizeHelper(const T (&array)[N]))[N];
#endif
#define arraysize(array) (sizeof(ArraySizeHelper(array)))

int a[10]
int size = arraysize(a);//这里能够求出a的大小

这个代码比普通的sizeof(a)/sizeof(int)更安全,它避免了我们做这样的操作:
int a[10]
int *= a;

int size = arraysize(p);//不可行
size = arraysize(a);//可行
利用模板获得一个数组的引用,返回对应的char类型的数组引用再对char类型的数组求大小,不用求sizeof(T),代替了了除法运算和两次求值sizeof(),不知道这个会不会影响编译时的效率
template <typename T, size_t N>
char (*ArraySizeHelper(const T (&array)[N]))[N];
#define arraysize(array) (sizeof(*ArraySizeHelper(array)))
据waiting4you的评论,也可以这样做: 
对于老的编译器,不允许返回数组的引用,但是返回指针数组应该是没有问题的,入口参数传递数组的引用也没有问题