Что лучше BOOST_MPL_ASSERT или BOOST_STATIC_ASSERT? - PullRequest
12 голосов
/ 11 октября 2008

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

Ответы [ 2 ]

15 голосов
/ 26 марта 2009

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

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

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

3 голосов
/ 11 октября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...