具有交替类型的 Variadic 模板参数包

Variadic Template Parameter Packs with Alternating Types

我想知道是否可以使用参数包捕获交替参数模式。例如,

template<typename T, size_t U, typename... Args>
class foo<T, U, Args...>
{
   public:
     foo() : my_T(nullptr), my_U(U) {}

   private:
     T* my_T;
     size_t my_U;
     foo<Args...> my_next_foo;
}

所以这是行不通的,因为 Args 是一个只有类型的参数包。有没有办法修改它,以便可以在可变参数模板中正确捕获类型名 T,size_t U 模式?谢谢

没问题,只写你自己的一对:

template <typename T, size_t U>
struct foo_pair { };

来一包:

template<typename T, size_t U, typename... Pairs>
class foo<foo_pair<T, U>, Pairs...> {
    ...
};

实例化如下:

foo<foo_pair<int, 4>, foo_pair<char, 17>, ...> f;

您可以将 Args 作为 std::tuple 传递给 foo。将 std::integral_constant 用于 U,而不是将整型常量作为模板参数传递给 std::tuple。然后 Args 参数包包含所有类型和大小对。

例如,在实例化 foo 时,您可以使用如下类型:

Foo<std::tuple<int, std::integral_constant<size_t, 5> >,
    std::tuple<char, std::integral_constant<size_t, 3> > >

实施foo时,您应该将参数包传递给另一个std::tuple并使用std::tuple_element到select元组的第N个元素。

这只是一种可能的方法,如果您使用类型列表,您可能会发现实施起来更容易 foo

根据我的经验,作为模板参数的值是第二位 class 公民。

将它们升级到第一个 class,使用别名:

template<std::size_t n>
using size = std::integral_constant<std::size_t, n>;

然后模式匹配:

template<class...>
struct foo;
template<>
struct foo<> {
  // empty
};
template<class T, size_t U, typename... Args>
struct foo<T, size<U>, Args...> {
  foo() : my_T(nullptr), my_U(U) {}

private:
  T* my_T;
  size_t my_U;
  foo<Args...> my_next_foo;
};

鲍勃是你的叔叔。

但是请注意,将 U 作为模板参数,然后将其存储为 运行 时间值,这是非常值得怀疑的。

foo 的用户必须做到:

foo< Chicken, size<3>, Dog, size<17> >

而不是

foo< Chicken, 3, Dog, 17 >

您可以创建一个 class 代表数据容器 T* my_Tsize_t my_U。有了它,您就可以实现您的模板了:

#include <array>

using std::size_t;

template<typename... Args>
struct foo;

template<typename T, size_t N>
struct foo<std::array<T, N>>
{
    std::array<T, N> array;
};

template<typename T, size_t N, typename... Args>
struct foo<std::array<T, N>, Args...>
{
    std::array<T, N> array;
    foo<Args...> next_array;
};

int main() {
    foo<std::array<char, 1>, std::array<short, 2>, std::array<int, 4>> foos;
}

注意:我正在使用 std::array 作为数据容器的替代品。