我发现this article会显示以下模板和一个用于获取数组大小的宏:
template<typename Type, size_t Size>
char ( &ArraySizeHelper(Type( &Array )[Size]) )[Size];
#define _countof(Array) sizeof(ArraySizeHelper(Array))
我发现以下部分完全不清楚。 sizeof
应用于函数声明。我希望结果是“函数指针的大小”。为什么它会获得“返回值的大小”呢?
答案 0 :(得分:6)
sizeof
适用于函数调用的结果,而不是声明。因此,它给出了返回值的大小,在这种情况下,它是对字符数组的引用。
模板使返回类型中的数组具有与参数数组相同数量的元素,该数组从宏中提供给函数。
最后,sizeof
随后应用于对此char数组的引用。引用上的sizeof
与类型本身上的sizeof
相同。从sizeof(char) == 1
开始,这给出了数组中元素的数量。
答案 1 :(得分:5)
template<typename Type, size_t Size>
char (&ArraySizeHelper(Type(&Array)[Size]))[Size];
#define _countof(Array) sizeof(ArraySizeHelper(Array))
sizeof
应用于函数声明。我希望结果是“函数指针的大小”。为什么它会获得“返回值的大小”呢?
它不是sizeof ArraySizeHelper
(这是非法的 - 不能将sizeof
作为一个函数),也不是sizeof &ArraySizeHelper
- 甚至不是隐式地从函数到指向函数的隐式转换标准明确禁止,对于C ++ 0x见5.3.3)。相反,sizeof ArraySizeHelper(Array)
等于sizeof
函数调用返回的值,即sizeof char[Size]
因此Size
。
答案 2 :(得分:3)
ArraySizeHelper
是一个函数模板,它返回一个大小为char
的{{1}}数组。该模板有两个参数,一个是 type (Size
),另一个是 value (即Type
)。
因此,当您将类型的对象(例如Size
)传递给函数时。编译器推导模板的两个参数:A[100]
变为Type
,A
变为Size
。
因此实例化的函数返回类型变为100
。由于永远不会评估char[100]
的参数,因此函数不需要定义。 sizeof
只需要知道sizeof
函数的返回类型。这相当于char[100]
,它返回100 - 数组的大小。
另一个有趣的要点是sizeof(char[100])
与其他原始类型( char 1 的变体除外)不依赖于编译器。它总是sizeof(char)
。因此,1
保证为sizeof(char[100])
。
1。根据标准,100
的所有变体的大小为1,无论是char
,char
,signed char
。
功能