2015-10-16 72 views
2
#include <string> 
#include <utility> 
#include <vector> 
#include <boost/hana.hpp> 
namespace hana = boost::hana; 

template <typename ...T> 
void indexed_T_work(T&& ...args) 
{ 
    auto indices = hana::range_c<std::size_t, 0, sizeof...(T)>; 
    auto types = hana::make_tuple(std::forward<T>(args)...); 
    hana::for_each(
     hana::zip(indices, types) 
     , [](auto&& pair_) { /* Do index-dependent work with each `T` */ } 
     ); 
} 

int main() 
{ 
    indexed_T_work(5, 13, std::vector<std::string>{}, 32.f, 42, "foo"); 
} 

我想在hana::tuplehana::range_c,但hana::range_c使用hana::zip不被认为是序列,这是hana::zip的要求。这个决定背后的推理是什么?我如何(习惯性地)在尊重这个决定的同时实现我的目标?为什么`boost :: hana :: range_c`不是序列?

回答

5

首先,有几种解决方案:

溶液1

auto indices = hana::to<hana::tuple_tag>(hana::range_c<std::size_t, 0, sizeof...(T)>); 
auto types = hana::make_tuple(std::forward<T>(args)...); 
hana::for_each(hana::zip(indices, types), hana::fuse([](auto i, auto&& x) { 
    // ... 
})); 

溶液2

auto indices = hana::range_c<std::size_t, 0, sizeof...(T)>; 
auto types = hana::make_tuple(std::forward<T>(args)...); 
hana::for_each(indices, [&](auto i) { 
    auto& x = types[i]; 
    // ... 
}); 

溶液3

auto types = hana::make_tuple(std::forward<T>(args)...); 
hana::size_c<sizeof...(T)>.times.with_index([&](auto i) { 
    auto& x = types[i]; 
    // ... 
}); 

(1)具有使每个args因为zip返回序列的序列的拷贝的缺点,和其中所有的花是由值。由于这可能不是您想要的,因此您应该在解决方案(2)(3)之间挑选您喜欢的任何一个,它们确实相当。

现在,为什么range s不建模Sequence概念是因为这没有意义。 Sequence概念要求我们能够使用hana::make函数创建任意Sequence。因此,对于任何Sequence标签S,hana::make<S>(...)都必须创建包含...的标签SSequence。但是,range必须在某个间隔中包含连续的integral_constant s。因此,如果rangeSequence,则hana::make<hana::range_tag>(...)应该包含任何...,如果...不是连续integral_constant s,则打破的不变量。例如,考虑

hana::make<hana::range_tag>(hana::int_c<8>, hana::int_c<3>, 
          hana::int_c<5>, hana::int_c<10>) 

这应该是一个rangeintegral_constant小号8,3,5,10,这没有任何意义。显示为什么range不能是Sequence的另一个类似示例是permutations算法。 permutations算法需要Sequence并返回包含所有排列的SequenceSequence。显然,由于range只能容纳integral_constant s,所以尝试创建rangerange是没有意义的。像这样的例子比比皆是。

换句话说,range太专业化,以模拟Sequence概念。拥有这样一个专业化结构的好处是编译时效率很高。缺点是它不是通用容器,有些操作无法完成(如zip)。但是,如果您知道折衷是什么,则可以完全采取range并将其转换为完整的序列。

相关问题