对于没有内置的 C++ 版本,有两种广泛使用static_assert
的静态断言实现。
第一个用于 Boost 并使用模板和该模板的特化:
template <bool> struct static_assert;
template <> struct static_assert<true> {}; // only true is defined
#define STATIC_ASSERT(x) static_assert<(x)>()
在这里,一旦要检查的条件为假,编译器就无法找到模板的通用版本并且编译失败。
第二个使用 a 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
而前者不能那样使用。
有什么理由更喜欢静态断言的前一个实现而不是后一个?