模板模板参数

看来理解模板模板参数会杀了我:(,请解释一下我在脑海中所迷惑的一些误解:

template<class T> class B {}; // A templated class 

这是另一个代码:

 template<template<class X> class Z = B> // problem is in this line for me class BB{}; 

注意模板类BB的参数列表中的行,即:

 template<class X> class Z = B 

现在我想问的是什么停止C ++认为Z不是另一个模板类Z即:

 template<class X> class Z{ } 

而不是认为Z类是模板参数本身。

非常感谢,我真的很感激任何帮助,以消除我的想法这种误解)

Mankarse已经回答了你的问题,但是我还是认为我会提醒你。

模板模板参数就像普通的模板types参数一样,只是它们匹配模板而不是具体的types:

 // Simple template class template <typename Type> class Foo { Type m_member; }; // Template template class template <template <typename Type> class TemplateType> class Bar { TemplateType<int> m_ints; }; 

如果有帮助的话,你可以像对待函数指针那样思考它们。 正常的函数只是接受像普通模板的参数只是接受types。 但是,一些函数接受接受参数的函数指针,就像模板模板types接受接受types的模板一样:

 void foo(int x) { cout << x << endl; } void bar(void (*f)(int)) { f(1); f(2); } 

在评论中回答你的问题:模板模板参数是不可能的。 然而,他们不可能的原因只是因为标准化委员会决定模板模板足够了,可能会让编译器实现者更容易。 这就是说,没有任何事情阻止委员会决定他们是可能的,那么像这样的事情将是有效的C ++:

 template <template <template <typename> class> class TemplateTemplateType> class Baz { TemplateTemplateType<Foo> m_foos; }; typedef Baz<Bar> Example; // Example would then have Bar<Foo> m_foos; // which would have Foo<int> m_ints; 

再一次,你可以看到函数指针的相似之处。

  types <=> values templates <=> functions of values template templates <=> functions of functions of values template template templates <=> functions of functions of functions of values 

Baz类似的function是:

 void baz(void (*g)(void (*f)(int))) { g(foo); } 

你会在哪里使用模板模板?

这是相当牵强的,但我可以想一个例子:一个非常通用的图谱search库。

图search中常用的两种algorithm是深度优先search(DFS)和广度优先search(BFS)。 两种algorithm的实现除了一个方面是相同的:DFS使用一堆节点,而BFS使用一个队列。 理想情况下,我们只需要将algorithm写入一次,将栈/队列作为参数。 另外,我们希望指定堆栈或队列的实现容器,以便我们可以执行如下操作:

 search<Stack, Vector>( myGraph ); // DFS search<Queue, Deque>( myGraph ); // BFS 

但什么是堆栈或队列? 那么,就像在STL中一样,一个栈或一个队列可以用任何types的容器来实现:vectors,deques,lists等,也可以是任何元素types的栈,所以我们的栈或队列将具有接口:

 Stack<Vector, int> // stack of ints, using a vector implementation Queue<Deque, bool> // queue of bools, using a deque implementation 

但是VectorDeque本身就是模板types!

所以最后,我们的Stack将是一个模板模板,如:

 template <template <typename> class Storage, typename Element> struct Stack { void push(const Element& e) { m_storage.push_back(e); } void pop() { m_storage.pop_back(); } Storage<Element> m_storage; }; 

而我们的searchalgorithm则必须是一个模板模板模板!

 template <template <template <typename> class, typename> class DataStructure, template <typename> class Storage, typename Graph> void search(const Graph& g) { DataStructure<Storage, typename Graph::Node> data; // do algorithm } 

这将是非常激烈的,但希望你明白了。

请记住:模板模板模板不是合法的C ++,所以这个整个graphicssearch的东西不会实际编译。 这只是一个“如果?” 🙂

这是语言的语法的一部分(这是巨大的和大量的上下文相关)。 如果template<class X> class Z出现在模板参数列表中,则它被解释为forms参数Z声明(类似元types;种类typestypes以相同的方式分类值)“模板上课采取一个阶级的论点“。