【问题标题】:How to recursively create a constexpr list using Boost hana ?如何使用 Boost hana 递归创建 constexpr 列表?
【发布时间】:2017-07-17 17:54:03
【问题描述】:

我之前问过一个关于创建编译时列表数据结构的问题,并被建议使用 Boost.hana

我试过这个基本的测试代码:

#include <boost/hana/tuple.hpp>
#include <boost/hana/for_each.hpp>
#include <boost/hana/concat.hpp>
#include <iostream>

namespace hana = boost::hana;

template<typename A, typename R> 
constexpr R parse(A count)
{
  if(count == 0)
  {
    return hana::make_tuple(0);
  }
  else
  {
    return parse(count - 1);
  }
}


int main() 
{ 
  constexpr auto l = parse(10);

  hana::for_each
  (
    l, 
    [](auto const& element) 
    {
      std::cout << element << std::endl;
    }
  );

}

但是,模板类型推导不起作用,因为递归函数的每次调用都返回不同的类型。 有没有解决的办法?

【问题讨论】:

    标签: c++ boost c++14 template-meta-programming


    【解决方案1】:

    在使用 hana 进行元编程时,您必须了解的主要内容是没有值 - 我们不是在操作数字之类的东西,我们是在操作类型。这些类型可能具有与之关联的值,但它们仍然是类型。术语是IntegralConstant

    你想要的是这样的:

    template <class C> 
    constexpr auto parse(C count)
    {
        if constexpr(count == 0_c) {
            return hana::tuple(count);
        } else {
            return hana::flatten(hana::make_tuple(
                hana::tuple(count),
                parse(count - 1_c)));
        }
    }
    
    constexpr auto l = parse(10_c);
    

    10_c 是 IntegralConstant 的一个实例,其值为 10。我们可以将其与基本情况下的0_c 进行比较。这看起来像是价值平等,这是使用 Hana 的真正好处,但它不是价值平等——它纯粹是基于类型的。

    parse(10_c) 的结果是 &lt;10,9,8,7,6,5,4,3,2,1,0&gt; 的编译时元组等价物。


    请注意:

    template<typename A, typename R> 
    constexpr R parse(A count);
    

    不是一个特别有用的函数模板,因为R 是一个非推导上下文,因此必须在调用站点指定。无论parse() 的主体如何,这都会使parse(10) 格式不正确。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-01
      • 1970-01-01
      • 2020-04-08
      相关资源
      最近更新 更多