You're forcing too eager instantiation by accessing the nested ::type
of std::common_type
before applying the lambda. Replace typename std::common_type<double, mpl::_1>::type
with std::common_type<double, mpl::_1>
and you should be all good.
EDIT: Apologies for the bad advice. I didn't see quite what you were doing. Trouble is that mpl::apply
will turn your placeholder expression into a lambda expression by first running it through mpl::lambda
. That will cause std::common_type<double, mpl::_1>
to be wrapped in an mpl::protect
, which will block it from being evaluated in the first pass, and mpl::if_
won't evaluate it in the second pass because it treats its second and third parameters as plain types, not placeholder expressions. You can use mpl::bind
to force std::common_type
to be evaluated before mpl::if_
. That way, mpl::if_
sees if_<some-condition, double, void>
, and all is right again.
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/bind.hpp>
#include <boost/mpl/quote.hpp>
namespace mpl = boost::mpl;
template<typename T, typename U> using common_type2 = std::common_type<T,U>;
using if2 = mpl::if_<
std::is_same<double, mpl::_1>,
mpl::bind<mpl::quote2<common_type2>, double, mpl::_1>,
void>;
using apply2 = boost::mpl::apply<if2, double>::type;
static_assert(std::is_same<apply2, double>::value, "works");
HTH!