Подтвердить что ты не робот

Что лучше BOOST_MPL_ASSERT или BOOST_STATIC_ASSERT?

Как я помню, BOOST_MPL_ASSERT был когда-то предпочтительным. Это все еще так? Кто-нибудь знает, почему?

4b9b3361

Ответ 1

[Отвечая на мой собственный вопрос]

Это зависит. Это сравнение яблок с апельсинами. Хотя подобные макросы НЕ взаимозаменяемы. Вот краткое описание того, как каждый работает:

BOOST_STATIC_ASSERT( P ) генерирует ошибку компиляции, если P != true.

BOOST_MPL_ASSERT(( P )) генерирует ошибку компиляции, если P::type::value != true.

Последняя форма, несмотря на требование двойных круглых скобок, особенно полезна, поскольку она может генерировать более информативные сообщения об ошибках, если в качестве предикатов использовать Boolean nullary Metafunctions из 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 С++ 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 менее подробный для кода, хотя его сообщения об ошибках могут быть менее ясными (в зависимости от вашего компилятора).

Ответ 2

BOOST_MPL_ASSERT (все еще) обычно считается лучше. Сообщения от него несколько легче увидеть (и понять, если вы используете BOOST_MPL_ASSERT_MSG). Несколько месяцев назад были разговоры об обесценивании BOOST_STATIC_ASSERT, хотя я думаю, что все в конце концов согласились, что в мире еще есть место.