As you can see here:
Transforms are typically of the form proto::when< Something, R(A0,A1,...) >. The question is whether R represents a function to call or an object to construct, and the answer determines how proto::when<> evaluates the transform. proto::when<> uses the proto::is_callable<> trait to disambiguate between the two. Proto does its best to guess whether a type is callable or not, but it doesn't always get it right. It's best to know the rules Proto uses, so that you know when you need to be more explicit.
For most types R, proto::is_callable checks for inheritance from proto::callable. However, if the type R is a template specialization, Proto assumes that it is not callable even if the template inherits from proto::callable.
The documentation proposes to solutions: you either wrap every invocation of do_eval<double>
with proto::call
or you simply specialize is_callable
inside the boost::proto namespace and forget about the problem.
namespace boost { namespace proto
{
// Tell Proto that do_eval2<> is callable
template<typename T>
struct is_callable<do_eval2<T> >
: mpl::true_
{};
}}
[Edit:] Here is the proto::call
alternative:
struct eval2
: proto::or_<
proto::when<proto::terminal<proto::_>, proto::_value>
, proto::otherwise<
proto::call<do_eval2<double>(proto::tag_of<proto::_>(),
eval2(proto::pack(proto::_))...)>>
>
{};