I will show you what is the critical difference between Boost.Lambda and Boost.Phoenix:
Boost.Phoenix supports (statically) polymorphic functors, while Boost.Lambda bundles are always monomorphic.
(At the same time, in many aspects, the two libraries can be combined, so they are not an exclusive choice.)
Let me illustrate (warning: code not tested.) :
Phoenix
In Phoenix, a functor can transform into a "lazy function" of the Phoenix (from http://www.boost.org/doc/libs/1_54_0/libs/phoenix/doc/html/phoenix/starter_kit/lazy_functions.html )
struct is_odd_impl{ typedef bool result_type;
is_odd is really polymorphic (like the is_odd_impl functor). This is_odd(_1) can act on anything (which makes sense). For example, in is_odd(_1)(2u)==true and is_odd(_1)(2l)==true . is_odd can be combined into a more complex expression without losing its polymorphic behavior.
Lambda try
The closer we can get to this in Boost.Lambda ?, we could define two overloads:
bool is_odd_overload(unsigned arg1){return arg1 % 2 == 1;} bool is_odd_overload(long arg1){return arg1 % 2 == 1;}
but to create a "lazy function" lambda, we will need to choose one of two:
using boost::lambda::bind; auto f0 = bind(&is_odd_overload, _1);
Even if we determine the version of the template
template<class T> bool is_odd_template(T arg1){return arg1 % 2 == 1;}
we will have to bind to a specific instance of the template function, for example
auto f3 = bind(&is_odd_template<unsigned>, _1);
Neither f1 , nor f2 , nor f3 are truly polymorphic, as the choice was made during the binding.
(Note 1: this may not be the best example, since everything may seem to work due to implicit conversions from unsigned to long, but that's another matter.)
To summarize, given the polymorphic function / functor, Lambda cannot bind to the polymorphic function (as far as I know), while Phoenix can. It’s true that Phoenix relies on the “Result of the Protocol” http://www.boost.org/doc/libs/1_54_0/libs/utility/utility.htm#result_of , but 1) at least it's possible, 2) It’s less problem in C ++ 11, where return types are very easy to infer, and this can be done automatically.
In fact, in C ++ 11, Phoenix lizards are still more powerful than the C ++ 11 built-in lambdas. Even in C ++ 14, where lambdas templates are implemented, Phoenix is still more general because it allows a certain level of introspection. (For this, other things, Joel de Guzman (Phoenix developer) was and remains ahead of his time.)