組み込みの を持たないバージョンの C++ では、広く使用されている static assert の実装が 2 つありますstatic_assert
。
最初のものはBoostで使用され、テンプレートとそのテンプレートの特殊化を使用します:
template <bool> struct static_assert;
template <> struct static_assert<true> {}; // only true is defined
#define STATIC_ASSERT(x) static_assert<(x)>()
ここで、チェックする条件が false になると、コンパイラはテンプレートの汎用バージョンを見つけることができず、コンパイルは失敗します。
2番目は次を使用しますtypedef
:
#define STATIC_ASSERT( x ) typedef char __STATIC_ASSERT__[( x )?1:-1]
ここで、チェックする条件に違反すると、コンパイラtypedef
はサイズ -1 の配列を試みますが、これは違法であるため、コンパイル時エラーが発生します。
コードを発行しないことが保証されており、次のように使用できるため、後者の方が優れています(ここから):
template<int Shift> class BinaryFlag {
STATIC_ASSERT( 0 <= Shift && Shift < sizeof( DWORD) * CHAR_BIT );
public:
static const DWORD FlagValue = static_cast<DWORD>( 1 << Shift );
};
#define BINARY_FLAG( n ) CBinaryFlag<n>::FlagValue
前者はそのようには使用できません。
後者よりも静的アサートの前者の実装を好む理由はありますか?