c++ - 为什么更喜欢基于模板的静态断言而不是基于 typedef 的静态断言?

标签 c++ templates visual-c++ static-assert

有两个 widely used没有内置 static_assert 的 C++ 版本的静态断言实现。

第一个在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]

这里一旦违反要检查的条件,编译器就会尝试 typedef 大小为 -1 的数组,这是非法的,因此会出现编译时错误。

对我来说后者更好,因为它保证不会发出任何代码,而且它可以像这样使用(来自 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

而前者不能那样使用。

有什么理由比后者更喜欢静态断言的前一种实现吗?

最佳答案

STATIC_ASSERT 的第二个版本不能在同一个 block 中一个接一个地使用。

template<int N, int M>
void foo ()
{
  STATIC_ASSERT(N<M), STATIC_ASSERT(M<0);  // error
};

Demo .

另一方面,在您发布的示例中,您不能使用第一个版本(因为它处理临时构造)。所以这两个版本都有自己的观众。我可以说第一个版本是编译和运行时的混合体。然而,第二个版本是纯粹的编译时间。

编辑:有时为了可读性,您可能希望将所有断言与comman 运算符放在一行中(在这种情况下只有最后一条指令有效)。我知道它们也可以放在 ; 中。但只是为了举个例子,这是一个用例。

同样,在某些情况下,对象构造可以,但在语法上放置 typedef 就不行了。所以所有这些都会落在同一个地方。

关于c++ - 为什么更喜欢基于模板的静态断言而不是基于 typedef 的静态断言?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6954284/

相关文章:

c++ - Xcode:严格的 C 编译?

c++ - 如何在Arduino/C/C++中将带有 bool 值的数组转换为字节?

c++ - 简单的钻头设置和清洁

python - Django 模板扩展问题

javascript - ng-bootbox : multiple custom modals on same view (same controller)

c++ - 为什么在返回对象 Mat 时堆损坏?

c++ - CMake - 前向声明构建错误

c++ - T::* 在模板参数中是什么意思?

c# - 虚拟属性是否比具体属性慢?

visual-studio-2010 - 在仅 DLL 的 Windows 上使用 ffMPEG?