据我记得,曾经更推荐使用 BOOST_MPL_ASSERT
。现在是否仍然如此?有人知道原因吗?
[回答自己的问题]
这要看情况。这是一个不可比较的苹果和橙子之间的比较。尽管相似,但这些宏并不可互换使用。以下是每个宏如何工作的摘要:
BOOST_STATIC_ASSERT( P )
如果 P != true
, 则生成编译错误。
BOOST_MPL_ASSERT(( P ))
如果 P::type::value != true
,则生成编译错误。
后者形式需要使用双括号,但尤其有用,因为如果使用Boost.MPL或TR1的<type_traits>
中的布尔零元元函数作为谓词,就可以生成更具信息量的错误消息。
下面是一个演示如何使用(和滥用)这些宏的示例程序:
#include <boost/static_assert.hpp>
#include <boost/mpl/assert.hpp>
#include <type_traits>
using namespace ::boost::mpl;
using namespace ::std::tr1;
struct A {};
struct Z {};
int main() {
// boolean predicates
BOOST_STATIC_ASSERT( true ); // OK
BOOST_STATIC_ASSERT( false ); // assert
// BOOST_MPL_ASSERT( false ); // syntax error!
// BOOST_MPL_ASSERT(( false )); // syntax error!
BOOST_MPL_ASSERT(( bool_< true > )); // OK
BOOST_MPL_ASSERT(( bool_< false > )); // assert
// metafunction predicates
BOOST_STATIC_ASSERT(( is_same< A, A >::type::value ));// OK
BOOST_STATIC_ASSERT(( is_same< A, Z >::type::value ));// assert, line 19
BOOST_MPL_ASSERT(( is_same< A, A > )); // OK
BOOST_MPL_ASSERT(( is_same< A, Z > )); // assert, line 21
return 0;
}
为了比较,这里是我的编译器(Microsoft Visual C++ 2008)对上述第19行和第21行产生的错误消息:
1>static_assert.cpp(19) : error C2027: use of undefined type 'boost::STATIC_ASSERTION_FAILURE<x>'
1> with
1> [
1> x=false
1> ]
1>static_assert.cpp(21) : error C2664: 'boost::mpl::assertion_failed' : cannot convert parameter 1 from 'boost::mpl::failed ************std::tr1::is_same<_Ty1,_Ty2>::* ***********' to 'boost::mpl::assert<false>::type'
1> with
1> [
1> _Ty1=A,
1> _Ty2=Z
1> ]
1> No constructor could take the source type, or constructor overload resolution was ambiguous
因此,如果您正在使用元函数(如此处定义),作为谓词,那么BOOST_MPL_ASSERT
在断言时既不那么冗长,而且更具信息量。
对于简单的布尔谓词,BOOST_STATIC_ASSERT
的代码更简洁,但其错误消息可能会较不清晰(取决于您的编译器)。
BOOST_MPL_ASSERT
(仍然)被普遍认为更好。它的信息更容易看到(如果您使用BOOST_MPL_ASSERT_MSG
,则更容易理解)。几个月前,有一些关于弃用BOOST_STATIC_ASSERT
的讨论,但我认为最终每个人都同意,在世界上仍有它的位置。