11

我最近开始使用 C++11,并且阅读了关于可变参数模板的教程。我知道我们可以像这样定义一个可变参数模板

// example class that uses variadic template
template<typename ...Args> struct mtuple;

但是如何处理mtuple类的模板参数(即get<int>(mtuple_obj)看起来如何?)?

4

2 回答 2

4

没有简单的机制来迭代可变参数模板的值。但这可以递归地完成。这是一个例子:

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我也会递归调用以检测额外的参数

来源:http ://en.wikipedia.org/wiki/Variadic_templates

于 2012-05-04T11:30:17.803 回答
4

外观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

于 2012-05-04T13:58:08.033 回答