auto plus_1 = phx::bind(&plus,1,arg1);
After this line, plus_1
is a function object that takes one int
argument and adds one to it.
phx::lambda[plus_1(arg1)](1);
Whoops. This isn't going to work because (as we said above) plus_1
is a function object that takes one int
argument and adds one to it. Here, you're trying to invoke it with arg1
.
It isn't obvious from your code what you expect it to do. Can you clarify?
====EDIT====
I see you've edited the code in your question. Your code is still wrong but for a different reason now. This:
phx::val(plus_1)(arg1)
... uses val
to create a nullary function that returns the plus_1
unary function. You then try to invoke the nullary function with arg1
. Boom.
Here is code that executes and does (what I believe) you intend:
#include <iostream>
#include <boost/phoenix/phoenix.hpp>
namespace phx = boost::phoenix;
using phx::arg_names::arg1;
int plus(int a,int b)
{
return a+b;
}
int main()
{
auto plus_1 = phx::bind(&plus, 1, arg1);
int value = phx::bind(phx::lambda[plus_1], arg1)(1);
std::cout << value << std::endl;
}
The first bind
takes the binary plus
and turns it into a unary function with the first argument bound to 1
. The second bind
creates a new unary function that is equivalent to the first, but it does so by safely wrapping the first function using lambda
. Why is that necessary? Consider the code below, which is equivalent, but without the lambda
:
// Oops, wrong:
int value = phx::bind(phx::bind(&plus, 1, arg1), arg1)(1);
Notice that arg1
appears twice. All expressions get evaluated from the inside out. First, we'll bind the inner arg1
to 1
, then evaluate the inner bind
yielding 2
, which we then try to bind and invoke. That's not going to work because 2
isn't callable.
The use of lambda
creates a scope for the inner arg1
so it isn't eagerly substituted. But like I said, the use of the second bind
, which forces the need for lambda
, yields a function that is equivalent to the first. So it's needlessly complicated. But maybe it helped you understand about bind
, lambda
and Phoenix scopes.