Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Advantages of using boost::mpl::bool_ instead of a const bool

I am confused about the advantages of using the the

bool_<true> 

and

bool_<false> 

types against simply using const bools in the context of template metaprogramming.

The boost::mpl library clearly prefers the first approach, and defines helper functions like and_, or_ to help manage such bool_. Conditional metafunctions like if_ "take" a bool_ as first (template) argument, but behind the scenes "call" a if_c metafunction which expects a (const) bool as first (template) argument.

What are the arguments behind this decision?

like image 842
StephQ Avatar asked Oct 21 '10 11:10

StephQ


2 Answers

Here is a short example, how I use these types every now and then. This example would not be possible, using const bool:

void do_something(boost::mpl::bool_<true>)
{
   ...
}

void do_something(boost::mpl::bool_<false>)
{
   ...
}

Call one of these two functions depending on the type of argument:

template<class T>
void doIt(void)
{
   do_something(boost::mpl::bool_<boost::is_pointer<T>::val>())
}

In this case either the first or the second function will be called, depending on the fact if type T is a pointer or not. These types allow you to use function overloading, where it would not be possible using a const bool. With a const bool you would have to decide at runtime, which branch to take. This is specially important if called functions are themselves templates, which would not compile correctly, if they were instantiated for types other than expected, e.g. the first function definition above might contain code, which only compiles for pointers.

like image 132
Martin Avatar answered Sep 28 '22 06:09

Martin


It's all about creating enough uniformity that the library can provide useful functionality. The MPL protocol is: "all metafunction arguments (and returns) are types." This allows us to write a templates that can operate generically on metafunctions. For example, this template accepts any metafunction (or any metafunction with up to N arguments in C++03):

template <template <class...> class some_metafunction>
struct wrapper;

Once you allow some of the template arguments to be non-types, writing such a wrapper becomes impossible. For a practical example of why we care, this uniformity allows the library to pick apart and evaluate MPL lambda expressions. If metafunction arguments were allowed to be non-types that feature would be unimplementable, because there would be no way to write out all the partial specializations needed to untangle the outer template xxx from its arguments ai in xxx<a1,a2,a3,...>.

A less-interesting, if not less-valid, part of the reason is that many things become less verbose the way we did it in MPL. compare:

and_<mf0<x,y>, mf1<z>, mf2<x,z> >::value

vs

mf0<x,y>::value && mf1<z>::value && mf2<x,z>::value
like image 34
Dave Abrahams Avatar answered Sep 28 '22 06:09

Dave Abrahams