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__)。