As I recall BOOST_MPL_ASSERT
was once preferred. Is this still true? Anyone know why?
views:
688answers:
3BOOST_MPL_ASSERT
is (still) generally considered better. The messages from it are somewhat easier to see (and understand, if you use BOOST_MPL_ASSERT_MSG
). There was some talk a few months ago about deprecating BOOST_STATIC_ASSERT
, though I think everyone eventually agreed that there's still room for it in the world.
[Answering my own question]
It depends. This is an apples to oranges comparison. Although similar, these macros are NOT interchangeable. Here's a summary of how each works:
BOOST_STATIC_ASSERT( P )
generates a compilation error if P != true
.
BOOST_MPL_ASSERT(( P ))
generates a compilation error if P::type::value != true
.
The latter form, despite requiring double parentheses, is especially useful because it can generate more informative error messages if one uses Boolean nullary Metafunctions from Boost.MPL or TR1's <type_traits>
as predicates.
Here is an example program that demonstrates how to use (and misuse) these macros:
#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;
}
For comparison, here are the error messages my compiler (Microsoft Visual C++ 2008) generated for lines 19 and 21 above:
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
So if you're using metafunctions (as defined here) as predicates then BOOST_MPL_ASSERT
is both less verbose to code and more informative when it asserts.
For simple boolean predicates, BOOST_STATIC_ASSERT
is less verbose to code although its error messages may be less clear (depending on your compiler.)