2008-10-11 7 views

Répondre

15

[Répondre à ma propre question]

Cela dépend. Ceci est une comparaison de pommes à oranges. Bien que similaires, ces macros ne sont pas interchangeables. Voici un résumé de la façon dont chacun fonctionne:

BOOST_STATIC_ASSERT(P) génère une erreur de compilation si P != true. Génère une erreur de compilation si P::type::value != true.

Cette dernière forme, malgré exigeant une double parenthèses, est particulièrement utile, car il peut générer plus d'information des messages d'erreur si on utilise booléennes nulaires métafonctions de Boost.MPL ou <type_traits> comme prédicats de TR1.

Voici un exemple de programme qui montre comment utiliser (et l'utilisation abusive) ces 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; 
} 

À titre de comparaison, voici les messages d'erreur mon compilateur (Microsoft Visual C++ 2008) généré pour les lignes 19 et 21 ci-dessus:

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 

donc, si vous utilisez métafonctions (tel que défini here) comme prédicats alors BOOST_MPL_ASSERT est à la fois moins bavard au code et plus instructif quand il affirme.

Pour prédicats simples booléens, BOOST_STATIC_ASSERT est moins bavard au code bien que ses messages d'erreur peuvent être moins claires (selon votre compilateur.)

3

BOOST_MPL_ASSERT est (encore) généralement considéré comme meilleur. Les messages de celui-ci sont un peu plus faciles à voir (et comprennent, si vous utilisez BOOST_MPL_ASSERT_MSG). Il y a eu quelques discussions il y a quelques mois sur la dépréciation BOOST_STATIC_ASSERT, bien que je pense que tout le monde a fini par accepter qu'il y avait encore de la place pour ça dans le monde.

Questions connexes