C++ 任意折叠多个可变包

C++ 任意折叠多个可变包,c++,c++11,metaprogramming,variadic-templates,C++,C++11,Metaprogramming,Variadic Templates,我正在阅读Eric Niebler关于他的小型元编程库的文章。在尝试实现他遗漏/列为挑战的部分时,我只剩下以下transform: template <typename F, typename... As> using meta_apply = typename F::template apply<As...>; template <typename... > struct typelist_transform; // unary template <

我正在阅读Eric Niebler关于他的小型元编程库的文章。在尝试实现他遗漏/列为挑战的部分时,我只剩下以下
transform

template <typename F, typename... As>
using meta_apply = typename F::template apply<As...>;

template <typename... >
struct typelist_transform;

// unary
template <typename... T, typename F>
struct typelist_transform<typelist<T...>, F> 
{
    using type = typelist<meta_apply<F,T>...>;
};

// binary
template <typename... T, typename... U, typename F>
struct typelist_transform<typelist<T...>, typelist<U...>, F>
{
    using type = typelist<meta_apply<F,T,U>...>;
};
模板
使用meta_apply=typename F::template apply;
模板
结构类型表转换;
//一元
模板
结构类型列表\u转换
{
使用类型=类型列表;
};
//二进制的
模板
结构类型列表\u转换
{
使用类型=类型列表;
};

这是可行的,但对我来说似乎很不满意-我需要对每一个“参数”进行
typelist\u transform
的部分专门化,将其转换为
F
。有没有更好的方法来实现这个元函数?

稍微修改一下界面(首先使用元函数,而不是最后一个,然后向
类型列表添加几个成员,以获得其大小和第N个成员,而不是使用独立的元函数):

然后

template<size_t... Ints, class F, class...Lists>
struct typelist_transform_helper<std::index_sequence<Ints...>, F, Lists...>{
    template <class MF, size_t N, typename... Ls>
    using apply_to_Nth = meta_apply<MF, typename typelist_indexer<Ls>::template get<N>...>;

    using type = typelist<apply_to_Nth<F, Ints, Lists...>...>;
};
模板
结构类型列表\转换\辅助对象{
模板
使用apply\u to\u Nth=meta\u apply;

使用type=typelist。

我想你可以使用类似的技巧,使用
tuple\u元素
来保持元函数的最后一个。@Barry是的,这是可以做到的。只需要更少的代码先拥有它。
template<class L>
struct typelist_indexer {
    template<size_t N, class T> struct helper_base { using type = T; };

    template<class S, class> struct helper;
    template<size_t... Ns, class... Ts> 
    struct helper<std::index_sequence<Ns...>, typelist<Ts...>> : helper_base<Ns, Ts>... {};

    template<size_t N, class T>
    static helper_base<N, T> do_get(helper_base<N, T>);

    using helper_type = helper<std::make_index_sequence<L::size>, L>;

    template<size_t N>
    using get = typename decltype(do_get<N>(helper_type()))::type;
};
template<size_t... Ints, class F, class...Lists>
struct typelist_transform_helper<std::index_sequence<Ints...>, F, Lists...>{
    template <class MF, size_t N, typename... Ls>
    using apply_to_Nth = meta_apply<MF, typename typelist_indexer<Ls>::template get<N>...>;

    using type = typelist<apply_to_Nth<F, Ints, Lists...>...>;
};