【问题标题】:unpacking variadic template arguments to define new template arguments解包可变参数模板参数以定义新的模板参数
【发布时间】:2026-02-13 17:45:01
【问题描述】:

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

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

}

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

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

}

例如,如果我使用 Class1&lt;10,20,25&gt; 我想在 Class1 的正文中 创建一个 Class2&lt;std::bitset&lt;10&gt;, std::bitset&lt;20&gt;, std::bitset&lt;25&gt;&gt; 多变的。有没有使用 C++11 的简单方法?

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

【问题讨论】:

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


    【解决方案1】:

    你可以这样写:

    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>...>
    

    【讨论】:

    【解决方案2】:

    我发现你可以这样想参数包上的 ... 运算符:

    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>...>
    

    第一个需要显式添加,因为它当然不是参数包的一部分。

    【讨论】:

      【解决方案3】:

      其他答案非常好,但让我给你一个更通用的公认答案版本。您基本上创建了一个 using 别名,它采用两个模板,第一个是将类模板作为模板参数保存的类,第二个是将类型传递给的模板(如 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...>;
      };
      

      还可以添加对接受值和类型的类的支持。

      【讨论】: