从另一个可变参数模板制作可变参数模板

Ser*_* Pv 8 c++ variadic-templates c++17

老实说,我不知道如何开始搜索我试图解决的问题的解决方案。可能已经有解决方案了。所以任务来了。

我有一个实际上是带有 2 个参数的模板的类:

template <typename F, typename S>
class trans {...};
Run Code Online (Sandbox Code Playgroud)

我还有另一个类,它包含一系列这些“反式”类,如元组(示例):

class holder {
    using chain_type = std::tuple<trans<std::string, int>, 
                                  trans<int, float>, 
                                  trans<float, std::string>, 
                                  trans<std::string, json>>;
};
Run Code Online (Sandbox Code Playgroud)

并且可以看出,“trans”的第二个参数与下一个参数相同。连锁,链条:

std::string -> int -> float -> std::string -> json.
Run Code Online (Sandbox Code Playgroud)

我想要什么......我想要一些方法来制作这样的链条:

std::string -> int -> float -> std::string -> json.
Run Code Online (Sandbox Code Playgroud)

是否可以?我对可变参数模板不是很熟悉,并且很少使用它们。

And*_*hev 9

对的,这是可能的:

template< typename F, typename S >
class trans {};

template< typename F, typename S, typename... Tail >
struct create_trans_chain;

template< typename F, typename S, typename... Tail >
using create_trans_chain_t = typename create_trans_chain< F, S, Tail... >::type;

template< typename F, typename S >
struct create_trans_chain< F, S >
{
    using type = std::tuple< trans< F, S > >;
};

template< typename F, typename S, typename Next, typename... Tail >
struct create_trans_chain< F, S, Next, Tail... >
{
    using type = decltype(std::tuple_cat(
        std::declval< create_trans_chain_t< F, S > >(),
        std::declval< create_trans_chain_t< S, Next, Tail... > >()));
};
Run Code Online (Sandbox Code Playgroud)


Bar*_*rry 6

使用Boost.Mp11,这很短(一如既往):

template <typename ...Args>
using trans_chain_create_t =
    mp_transform<trans,
        mp_pop_back<std::tuple<Args...>>,
        mp_pop_front<std::tuple<Args...>>>;
Run Code Online (Sandbox Code Playgroud)

mp_transform基本上是 a zip,我们Args用(Args没有头部)压缩(没有尾部),然后成对地应用trans它。


您可以通过添加辅助元函数来拆分上述内容zip_tail

template <template <typename...> class F, typename L>
using zip_tail = mp_transform<F, mp_pop_back<L>, mp_pop_front<L>>;

template <typename ...Args>
using trans_chain_create_t = zip_tail<trans, std::tuple<Args...>>;
Run Code Online (Sandbox Code Playgroud)