从boost :: phoenix :: lambda中调用函数

时间:2013-04-06 13:34:38

标签: c++ boost c++11 boost-phoenix

我正在尝试使用boost::phoenix在缺少C ++ 11支持的旧编译器上模拟C ++ lambda表达式,并且我无法在lambda表达式中调用简单函数。

C ++ 11版本:

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

我的Phoenix Lambda代码如下:

#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;
}

这会产生以下编译器错误:

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>’

如何在Phoenix lambda表达式中调用函数?

我希望能够以与过去使用C ++ 11 lambdas相同的方式使用phoneix::lambdas,例如:

auto lambda1 = [&]( uint32_t arg )
              {
                  func1( "Some Stuff", arg );
                  func2( "Some More Stuff", aValueFromLocalScope, arg );
                  func3( "Some Stuff", anotherValueFromLocalScope, arg );
              };

someFuncImpl( aParam, lambda1 );

2 个答案:

答案 0 :(得分:6)

ph::lambda是这项工作的错误工具(ph::lambda是一个用于在phoenix表达式中创建嵌套lambda表达式的工具)。 Phoenix表达式是已经的函数,所以你需要做的就是找到一种方法来使用phoenix表达式调用函数(bind),找到一种方法来按顺序执行多个操作(operator,),然后查找一种引入局部变量的方法(let)。把这一切放在一起给出了:

#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;
}

答案 1 :(得分:4)

如果您的示例是微不足道的并不重要。调用非Phoenix函数需要使用phoenix::bind。周期。

凤凰式lambda最有效地用于简单的基于运算符重载的表达式。调用任意函数看起来很难看。

C ++ 11没有添加lambda作为语言功能,因为它很有趣。他们这样做是因为各种图书馆解决方案在某些方面都不充分。你发现了凤凰城的一个不足之处。