对于没有内置static_assert
的C++版本,静态断言有两种widely used实现。
第一个在Boost中使用,并使用a template and a specialization of that template:
template <bool> struct static_assert;
template <> struct static_assert<true> {}; // only true is defined
#define STATIC_ASSERT(x) static_assert<(x)>()
在这里,一旦检查条件为假,编译器便无法找到模板的通用版本,并且编译失败。
第二个使用
typedef
:#define STATIC_ASSERT( x ) typedef char __STATIC_ASSERT__[( x )?1:-1]
在这种情况下,一旦违反检查条件,编译器将尝试对大小为-1的数组进行
typedef
编码,这是非法的,因此会产生编译时错误。对我来说,后者更好,因为它保证不会发出任何代码,并且也可以像这样使用(来自here):
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
而前者不能那样使用。
有没有理由比静态断言更喜欢前一种实现?
最佳答案
我通常在自己的代码中使用了第二个或其他形式。
实际上,Boost变体的优点是可以使用
表达式可能出现的任何地方,而不仅仅是语句级别。它
缺点是只能在表达式可以使用的地方使用
出现,因此不在命名空间范围内。