tags:

views:

688

answers:

3

As I recall BOOST_MPL_ASSERT was once preferred. Is this still true? Anyone know why?

+2  A: 

BOOST_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.

Head Geek
A: 

couldn't find tutorial, but some doc here boost_mpl_assert

Dustin Getz
+2  A: 

[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.)

jwfearn