解压缩可变参数模板参数以定义新的模板参数

时间:2018-09-28 23:18:07

标签: c++ c++11 templates variadic-templates

我是模板编程的新手,我有两个问题...希望有人可以帮助我。 我正在尝试使用可变参数模板为另一个可变参数模板生成新的输入。 换句话说,我有一堂课

template <std::size_t N, std::size_t... M>
class Class1 {

}

我想使用N,M表示的整数值来生成另一组模板类的std :: bitset类型输入的新集合

template <typename T, typename... Ts>
class Class2 {

}

例如,如果我使用Class1<10,20,25>,我想在Class1的正文中 创建一个 Class2<std::bitset<10>, std::bitset<20>, std::bitset<25>> 变量。是否有使用C ++ 11做到这一点的简单方法?

然后我的第二个问题是如何进一步抽象它,以便解包不是特定于std::bitset类的? 有没有一种方法可以修改Class1模板定义,以便可以扩展我开发的任意模板类而不是std::bitset

3 个答案:

答案 0 :(得分:9)

您可能会写类似:

template <std::size_t N, std::size_t... M>
class Class1 {
    template <template <typename, typename...> class C,
              template <std::size_t> class inner>
    using rebind_with_type = C<inner<N>, inner<M>...>;
};

然后

Class1<10, 20, 25>::rebind_with_type<Class2, std::bit_set>
// -> Class2<std::bit_set<10>, std::bit_set<20>, std::bit_set<25>>

如果使用相关名称进行调用,请不要忘记typename / template

typename Class1<N, M...>::template rebind_with_type<Class2, std::bit_set>
// -> Class2<std::bit_set<N>, std::bit_set<M>...>

答案 1 :(得分:4)

我发现您可以通过以下方式想到参数包上的...运算符:

f(g(Xs)...);

将扩展为

f(g(Xs1), g(Xs2), ..., g(Xsn));

对于任何操作f和g。实际上,它所做的就是添加一个逗号分隔的g列表,该列表应用于提供的每个参数。 ...定义了应该从哪里开始扩展 这些操作可以用于类型或值,因此在您的情况下,我们的f是Class2 <...>,而我们的g是std :: bitset,我们的类型应该是

Class2<std::bitset<N>, std::bitset<M>...>

第一个必须明确添加,因为它不是课程参数包的一部分。

答案 2 :(得分:1)

其他答案非常好,但是让我给您一个更通用的版本。基本上,您创建了一个使用别名,该别名使用两个模板,第一个是将类模板作为模板参数保存的类,第二个是您要将类型传递给的模板(例如bitset)。

template<template<class...> class Y, template<class...> class Z, class... Ts>
using fold_types_into_t = Y<Z<Ts>...>;
template<template<class...> class Y, template<auto...> class Z, auto... Vs>
using fold_values_into_t = Y<Z<Vs>...>;

template<class,class...>
struct Class2;

template <std::size_t N, std::size_t... M>
class Class1 {
  // Class2<std::bitset<10>, std::bitset<20>, std::bitset<25>>
  using T=fold_values_into_t<Class2, std::bitset, N, M...>;
};

还可以添加对包含值和类型的类的支持。

相关问题