2017-07-17 54 views
1

我以前问一个问题关于创建编译时列表数据结构,并建议使用Boost.hana如何使用Boost hana递归创建一个constexpr列表?

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

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

} 

但是,模板类型扣不工作,因为递归函数的每次调用都返回一个不同的类型。 有没有办法解决这个问题?

回答

2

当你用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)的结果是<10,9,8,7,6,5,4,3,2,1,0>的编译时元组等效值。


需要注意的是这样的:

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

不是一个特别有用的功能模板,因为R是一种非推断上下文,因此必须在调用点指定。无论parse()的身体如何,parse(10)都不合格。