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)で回答が機能することをさらに望んでいますが、好奇心のために、明確な回答は何でも構いません。