If I have a type, T, that looks like Foo<mpl::_1>, I can do mpl::apply<T, int>::type to get Foo<int>.
But if T is a complete type like, say, Foo<int>, then mpl::apply<T, int>::type will not compile.
I want to write a metafunction that will apply a type if possible, otherwise return the type. So something like:
template <typename Partial, typename T>
struct maybe_apply
: eval_if_c<??????,
mpl::apply<Partial, T>,
mpl::identity<Partial>>
{ };
What can I put in the ???s so that this does what I want?
Disclaimer: I'm far from an expert on MPL, so I can't promise that this is the best way to solve this (or even if it is correct, it seems to work at least).
According to the documentation, the first parameter/argument to
mpl::applyneeds to be a Lambda Expression, and that can be either a Metafunction Class or a Placeholder Expression. A quick google search led me to this post. According to that post,mpl::is_lambda_expressionallows you to determine if a type is a Placeholder Expression. In Boost.TTI (that is in boost since version 1.54) you can find a metafunction that does exactly what you want. This metafunction isboost::tti::detail::is_lambda_expressionand can be found inboost/tti/detail/dlambda.hpp. In the example below I have used the exact same macro that TTI uses to find if a type is a Metafunction Class.Running on Coliru.