BOOST_STATIC_ASSERT的使用和实现原理

如果大家用的是VC2010及以上版本的编译器的话,可以直接使用C++ 0x标准中的static_assert,这些编译器都是支持这个新标准的。

而我好奇的是boost是怎么实现这个的,非常简单,就几行代码。

#define BOOST_STATIC_ASSERT( B ) \
   typedef ::boost::static_assert_test<\
      sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST ( B ) >)>\
         BOOST_JOIN(boost_static_assert_typedef_, __COUNTER__)

 

// HP aCC cannot deal with missing names for template value parameters
template <bool x> struct STATIC_ASSERTION_FAILURE;

template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };

// HP aCC cannot deal with missing names for template value parameters
template<int x> struct static_assert_test{};

我们使用的是BOOST_STATIC_ASSERT(expr);这个宏看上去挺长挺吓人的,下面一层层的剥开它。

首先对表达式求值,并将结果转换为bool类型,这是由BOOST_STATIC_ASSERT_BOOL_CAST ( B )完成的。

然后,用求出的结果作为模板参数传给STATIC_ASSERTION_FAILURE类模板,使用sizeof计算结构大小。但是,如果计算出的表达式的结果为false,由于没有特化这个类,所以就会很自然的编译出错。

sizeof的结果又作为static_assert_test的模板参数。

最后又是一层typedef,所以使用BOOST_STATIC_ASSERT链接后不会增加任何汇编代码。

BOOST_JOIN很简单,boost_static_assert_typedef_## __COUNTER__)。

posted @ 2013-01-27 16:32  avexer  阅读(1020)  评论(0编辑  收藏  举报