加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 在Boost Phoenix表达式中转换函数体

发布时间:2020-12-16 05:03:35 所属栏目:百科 来源:网络整理
导读:如何在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 { re
如何在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;

然后我从previous question准备一个简单的加号 – 减号变换,如下所示:

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

但是,当我将一个倒置的Phoenix lambda表达式(使用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;
}

解决方法

答案非常简单,你会踢自己.您编写的表达式转换知道如何将加号节点转换为减法节点.但是你传递给它的表达式中没有加号节点.再看一遍:
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::vararg<invrt> >
    >
  >
{};

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

  std::cout << f()(1,2) << std::endl; // -1,w00t!
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读