模板模板参数
看来理解模板模板参数会杀了我:(,请解释一下我在脑海中所迷惑的一些误解:
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
但是Vector
和Deque
本身就是模板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; };
而我们的search
algorithm则必须是一个模板模板模板!
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以相同的方式分类值)“模板上课采取一个阶级的论点“。