对于没有内置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变体的优点是可以使用
表达式可能出现的任何地方,而不仅仅是语句级别。它
缺点是只能在表达式可以使用的地方使用
出现,因此不在命名空间范围内。

07-24 14:14