5

如何在 Boost Phoenix 表达式的转换中也包含函数体?

例如,我在Boost Phoenix Starter Kit的 Lazy Functions 部分构建,并创建了一个惰性添加函数:

struct my_lazy_add_impl {
  typedef int result_type;
  template <typename T>
  T operator()(T x, T y) const { return x+y; }
};
phoenix::function<my_lazy_add_impl> my_add;

然后,我从上一个问题准备一个简单的正负转换,如下所示:

struct invrt:
  proto::or_<
    proto::when<
      proto::plus<proto::_, proto::_>,
      proto::functional::make_expr<proto::tag::minus>(
        invrt(proto::_left), invrt(proto::_right)
      )
    >,
    proto::otherwise<
      proto::nary_expr<proto::_, proto::vararg<invrt> >
    >
  >
{};

但是,当我使用 , 对其参数应用一个倒置的 Phoenixlambda表达式时,my_add如下所示,似乎没有实现预期的倒置。有没有推荐的方法在 Phoenix 中实现函数调用,可以促进这种转换?

int main(int argc, char *argv[])
{
  auto f =         phoenix::lambda(_a = 0)[my_add(_1,_2)];
  auto g = invrt()(phoenix::lambda(_a = 0)[my_add(_1,_2)]);
  std::cout << f()(1,2) << std::endl; // 3
  std::cout << g()(1,2) << std::endl; // 3 again; alas not -1
  return 0;
}
4

1 回答 1

3

答案真的很简单,你会踢自己。您编写的表达式转换知道如何将加节点转换为减节点。但是您传递给它的表达式中没有加号节点。再看一遍:

auto g = invrt()(phoenix::lambda(_a = 0)[my_add(_1,_2)]);

加号节点在哪里?对于 Proto(和 Phoenix)来说,my_add是不透明的。他们不知道里面有一个额外的东西。他们怎么可能?

====编辑====

考虑一下这个,它可以满足您的意图:

#include <iostream>
#include <boost/phoenix.hpp>
#include <boost/proto/proto.hpp>
namespace proto = boost::proto;
namespace phoenix = boost::phoenix;
using namespace phoenix::arg_names;
using namespace phoenix::local_names;

auto const my_add = phoenix::let(_a = _1, _b = _2)[_a + _b];

struct invrt:
  proto::or_<
    proto::when<
      proto::plus<proto::_, proto::_>,
      proto::functional::make_expr<proto::tag::minus>(
        invrt(proto::_left), invrt(proto::_right)
      )
    >,
    proto::otherwise<
      proto::nary_expr<proto::_, proto::vararg<invrt> >
    >
  >
{};

int main()
{
  auto f =         phoenix::lambda(_a = 0)[my_add(_1,_2)];
  auto g = invrt()(phoenix::lambda(_a = 0)[my_add(_1,_2)]);

  std::cout << f()(1,2) << std::endl; // 3
  std::cout << g()(1,2) << std::endl; // -1, w00t!
}
于 2013-03-07T01:02:21.463 回答