我最近开始使用 C++11,并且阅读了关于可变参数模板的教程。我知道我们可以像这样定义一个可变参数模板
// example class that uses variadic template
template<typename ...Args> struct mtuple;
但是如何处理mtuple
类的模板参数(即get<int>(mtuple_obj)
看起来如何?)?
我最近开始使用 C++11,并且阅读了关于可变参数模板的教程。我知道我们可以像这样定义一个可变参数模板
// example class that uses variadic template
template<typename ...Args> struct mtuple;
但是如何处理mtuple
类的模板参数(即get<int>(mtuple_obj)
看起来如何?)?
没有简单的机制来迭代可变参数模板的值。但这可以递归地完成。这是一个例子:
template<typename T, typename... Args>
void print_values(const char *s, T value, Args... args)
{
while (*s) {
if (*s == '%' && *(++s) != '%') {
std::cout << value;
++s;
print_values(s, args...);
return;
}
cout << *(s++);
}
}
所以,如果我打电话,print_values("%d %d %d", 1, 2, 3)
我会得到这个递归树:
print_values("%d %d %d", 1, 2, 3) // value -> 1, args... -> 2,3
print_values("%d %d", 2, 3) // value -> 2, args... -> 3
print_values("%d", 3) // value -> 3, args... -> NULL
print_values("") // value -> NULL, args... -> NULL
print_values()
即使 *s == 0我也会递归调用以检测额外的参数
外观get<1>(t)
将取决于. mtuple
典型的实现递归地继承自包含每个参数的类型,因此mtuple<A,B,C>
继承自TupleHead<A>
(具有 type 的成员A
)并且还继承自 TupleTail<B,C>
。 TupleTail<B,C>
继承自TupleHead<B>
(具有类型的成员B
)和TupleTail<C>
. TupleTail<C>
继承自TupleHead<C>
(它有一个类型的成员C
。)
现在,如果你也给每个基类一个整数参数:
mtuple<A,B,C>
继承自TupleHead<0,A>
和TupleTail<1,B,C>
TupleTail<1,B,C>
继承自TupleHead<1,B>
和TupleTail<2,C>
TupleTail<2,C>
继承自TupleHead<2,C>
现在写起来相对简单get<1>
,因为它mtuple
有一个唯一的类型基类,TupleHead<1,B>
可以通过向上转换获得,然后返回该B
基类的成员。
[编辑:get<1>(m)
需要知道B
与索引为 1 的元组元素对应的类型,因为您使用类似的东西,std::tuple_element
它也依赖于上述递归继承层次结构并使用部分特化来获取TupleHead<1,T>
索引为 1 的基类,然后确定T
该部分专业化中的参数,B
在我的示例中给出。]
可变参数模板使用的许多技术都是函数式编程技术,例如对模板参数包的第一个元素进行操作,然后对包的其余部分递归地执行相同的操作,直到处理完所有元素。除了计算它的大小(用sizeof...
)或用它实例化另一个模板之外,您可以直接使用模板参数包做的事情并不多,因此通常的方法是实例化另一个模板,将包Args
分成ArgHead, ArgsTail...
并处理头部,然后递归做同样的事情ArgsTail