如何使用Boost Hana删除元编程递归 [英] How to remove metaprogramming recursion with Boost Hana

查看:124
本文介绍了如何使用Boost Hana删除元编程递归的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试根据发送给函数的类型创建一个位集.但是让我们稍微减少一下测试用例.

I'm trying to create a bitset according to the type send to the function. But let's reduce the test case a little.

警告:在此示例中,我使用的是自动gcc扩展程序,不需要使用模板参数.

Warning : I'm using auto gcc extension for this example, I don't need to use template parameter.

namespace hana = boost::hana;

constexpr decltype(auto) rec(auto i, auto max, auto f, auto returnValue) {

  return returnValue |= f(i);
  if constexpr (i < max) //"infinite" loop if no constexpr
    return rec(i + hana::size_c<1>, max, f, returnValue);
  else
    return returnValue;
}

constexpr decltype(auto) foo(auto ct, auto ... type) {

  constexpr auto tuple = hana::make_tuple(type...);
  constexpr unsigned long returnValue = 0L;

  constexpr auto f = [tuple, ct] (auto i) {
    if (hana::contains(tuple, ct[i]))
      return 0 << decltype(i)::value;
    else
      return 0;
  };

  return rec(hana::size_c<0>, hana::size_c<3>, f, returnValue);
}

struct T1 {};
struct T2 {};
struct T3 {};

int main () {

  constexpr auto t1 = hana::type_c<T1>;
  constexpr auto t2 = hana::type_c<T2>;
  constexpr auto t3 = hana::type_c<T3>;
  constexpr auto ct = hana::make_tuple(t1, t2, t3);
  constexpr auto test = foo(ct, t1, t2);
}

好像我的元组不被认为是可搜索的,但是如果我尝试相同的hana ::包含在lambda之外,我就没问题.

Seems like my tuple is not considered Searchable, but if I try the same hana::contains outside the lambda I got no problem.

整个错误很大,因此请在此处进行检查:实时演示

The whole error is huge so check it there : live demo

顺便说一句,我尝试使用for循环执行此操作,但失败了.您知道在C ++ 17/20中做这种事情的好方法吗?

By the way, I tried to do this with a for loop but failed. Do you know a good way of doing this kind of things in C++17/20 ?

推荐答案

该错误是由于使用手动递归导致的越界访问引起的.函数式编程的部分目的是提供一种构造,以消除此类错误的可能性.

The error is caused by an out of bounds access caused by the use of manual recursion. Part of the purpose of functional programming is to provide constructs to eliminate the possibility of these kinds of mistakes.

这里有一些示例,但是建议您阅读有关该概念的手册

Here are a few examples, but it is recommended to take a look at the manual for the concept hana::Foldable as it is really foundational in using Boost.Hana.

hana::fold_left 为您隐藏递归并可以减少递归通过快速跟踪进行的递归调用量:

hana::fold_left hides the recursion for you and can reduce the amount of recursive calls via fast-tracking:

constexpr decltype(auto) foo = [](auto ct, auto ... type) {
  constexpr auto tuple = hana::make_tuple(type...);

  return hana::fold_left(hana::make_range(hana::size_c<0>, hana::size_c<3>), 0L,
    [tuple, ct](auto returnValue, auto i)
    {
      // returnValue param is not constexpr
      if (hana::contains(tuple, ct[i])) {
        return returnValue | (1 << decltype(i)::value);
      }
      else
      {
        return returnValue;
      }
    }
  );
};

hana :: fold_left示例

hana::unpack 使用可变包扩展完全消除了递归:

hana::unpack eliminates recursion altogether using variadic pack expansion:

constexpr decltype(auto) foo = [](auto ct, auto ... type) {
  constexpr auto tuple = hana::make_tuple(type...);
  auto f = [tuple, ct](auto i)
  {
    return hana::contains(tuple, ct[i]) ? (1 << decltype(i)::value) : 0;
  };

  return hana::unpack(hana::make_range(hana::size_c<0>, hana::size_c<3>),
    [f](auto ...i) { return (f(i) | ...); }
  );
};

hana :: unpack示例

这篇关于如何使用Boost Hana删除元编程递归的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆