Function call from boost :: phoenix :: lambda

I am trying to use boost::phoenix to emulate C ++ iambda expressions for an older compiler that does not support C ++ 11, and I cannot call a simple function from a lambda expression.

C ++ 11 Version:

 [](unsigned a) { foo( a ); }( 12678u ); // calls foo( 12678u ) 

My Phoenix Lambda code is as follows:

 #include <cstdint> #include <iostream> #include <boost/phoenix.hpp> namespace ph = boost::phoenix; using ph::local_names::_a; using ph::placeholders::arg1; void foo( uint32_t val ) { std::cout << "\t" << __func__ << "( " << val << " ) called...\n"; } int main() { auto myLambda = ph::lambda( _a = arg1 ) [ foo( _a ) //std::cout << ph::val( "Called with: " ) << _a << ph::val( "\n" ) ]( 567u ); myLambda(); return 0; } 

This results in the following compiler error:

 lambda-ex.cpp: In function 'int main()': lambda-ex.cpp:18:19: error: cannot convert 'const _a_type {aka const boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::phoenix::detail::local<boost::phoenix::local_names::_a_key> >, 0l> >}' to 'uint32_t {aka unsigned int}' for argument '1' to 'void foo(uint32_t)' lambda-ex.cpp:20:15: error: unable to deduce 'auto' from '<expression error>' 

How do I call a function from a Phoenix lambda expression?

I hope that I can use phoneix::lambdas in the same way as in the past I used C ++ 11 lambdas, for example:

 auto lambda1 = [&]( uint32_t arg ) { func1( "Some Stuff", arg ); func2( "Some More Stuff", aValueFromLocalScope, arg ); func3( "Some Stuff", anotherValueFromLocalScope, arg ); }; someFuncImpl( aParam, lambda1 ); 
+4
source share
2 answers

ph::lambda is the wrong tool for this job ( ph::lambda is a tool for creating nested lambda expressions inside a phoenix expression). Phoenix expressions are already functions, so all you have to do is find a way to call functions using phoenix expressions (bind), find a way to perform several operations in a sequence (operator), and find a way to introduce local variables (allow). Combining all of this gives:

 #include <cstdint> #include <iostream> #include <boost/phoenix.hpp> namespace ph = boost::phoenix; using ph::local_names::_a; using ph::placeholders::arg1; #define FOO(name) void name( uint32_t val ) {\ std::cout << "\t" << __func__ << "( " << val << " ) called...\n";\ } FOO(foo) FOO(bar) FOO(baz) int main() { auto&& myLambda = ph::let(_a = arg1) [ ph::bind(foo, _a), ph::bind(bar, _a), ph::bind(baz, _a) ]; myLambda(342); return 0; } 
+6
source

It doesn't matter if your example is trivial or not. Calling functions other than Phoenix requires using phoenix::bind . Period.

Phoenix-style lambdas are most efficiently used for simple operator-overloaded expressions. Calling arbitrary functions will look ugly.

C ++ 11 did not add lambdas as a language function because it was fun. They did this because the various library solutions were somehow inadequate. You have found one of the shortcomings of the Phoenix.

+4
source

All Articles