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

Calling a function from within a boost::phoenix::lambda

本文关键字:调用 函数 phoenix boost lambda      更新时间:2023-10-16

我试图使用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 lambda一样使用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 );

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

您的示例是否琐碎并不重要。调用非phoenix函数需要使用phoenix::bind。时期。

phoenix风格的lambdas最有效地用于基于操作符重载的简单表达式。调用任意函数看起来会很难看。

c++ 11没有添加lambdas作为一种语言特性,因为它很有趣。他们这样做是因为各种各样的图书馆解决方案在某种程度上都是不够的。你发现了凤凰的不足之处