我想知道是否可以使用参数包捕获交替参数模式。例如,
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只是一个类型的参数包。有没有办法修改它,以便可以在可变参数模板中正确捕获typename T,size_t U模式?感谢
答案 0 :(得分:4)
根据我的经验,作为模板参数的值是二等公民。
使用别名将它们升级到第一类:
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 >
答案 1 :(得分:2)
当然,只需编写自己的一对:
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;
答案 2 :(得分:0)
您可以将Args
作为foo
传递给std::tuple
。将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
来选择元组的第N个元素。
这只是一种可能的方法,如果使用类型列表,您可能会发现更容易实现foo
。
答案 3 :(得分:0)
您可以使用T* my_T
创建一个表示数据容器size_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作为数据容器的替代品。