The code below reproduces a behavior I really don't understand of the boost MPL library:
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/plus.hpp>
using namespace boost;
int main() {
typedef mpl::int_<1> one;
typedef mpl::int_<2> two;
typedef mpl::int_<3> three;
// The following line breaks compilation...
// static_assert( is_same< mpl::plus<one,two>::type, three >::type::value, "Not the same type");
// ...while this works
static_assert( mpl::plus<one,two>::type::value == three::value , "Not the same value");
return 0;
}
The question I have is: why mpl::plus<one,two>::type
is not the same type as three
?
I ran into this issue while trying to solve the exercises at the end of chapter 3 of
C++ Template Meta-Programming. I already tried to peek at <boost/mpl/plus.hpp>
and the includes therein, but the code was too complicated for me to be understandable.
The return type of plus
is only guaranteed to be an integral constant. You have no guarantee over it's exact type, hence your assert is allowed to fail.
The exact types are this:
mpl::plus<one,two>::type == mpl_::integral_c<int, 3>
three == foo<mpl_::int_<3> >
This is unintuitive. One problem is that plus<int_, int_>
theoretically can return a integral_c
where the first argument has a larger capacity then int_
in case of overflow.
For debugging a type printer
can be useful:
template<typename> print; // undefined instantiation leads to error with name
print<three> x; // nice error message