Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which is better BOOST_MPL_ASSERT or BOOST_STATIC_ASSERT?

Tags:

c++

boost

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

like image 772
jwfearn Avatar asked Oct 11 '08 00:10

jwfearn


1 Answers

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

like image 64
jwfearn Avatar answered Nov 14 '22 16:11

jwfearn