我正在阅读Modern C ++设计,但无法完全理解模板模板参数的工作原理。
例如,如本文http://www.informit.com/articles/article.aspx?p=376878中给出的,我们可以使用类型和容器的模板参数创建一个Stack。
如果我们只使用type和container作为模板Stack的参数,那么它可能会产生一些问题,比如
template <typename T, class Cont>
class Stack;
template <typename> class List;
Stack<int, List<int> > aStack1; // OK
Stack<double, List<int> > aStack2; // legal, not OK
Stack<std::string, Deque<char *> > aStack3; // error!
在上面的代码中,我可以理解aStack1没问题,aStack2和aStack3是问题,因为如果Stack元素类型和容器元素类型之间存在不兼容的类型。
根据文章,如果我们使用模板模板参数
,这可以解决template <typename T, template <typename> class Cont>
class Stack;
Stack<int,List> aStack1;
Stack<std::string,Deque> aStack2;
我怀疑Deque是如何知道它的元素类型是std :: string或者List元素类型是int ???这是通过模板参数推导完成的吗?
这里我们创建一个类型为T的Deque。 如果我们将堆栈定义为
template <typename T,template U, template <typename> class Cont>
class Stack;
然后我们如何实例化Stack
Stack<std::string,int,Deque> // will this work????
答案 0 :(得分:4)
我怀疑Deque是如何知道它的元素类型是std :: string或者List元素类型是int ???这是通过模板参数推导完成的吗?
不,您在Stack
的实现中显式实例化了类模板,该模板可能实现为:
template <typename T, template <typename> class Cont>
class Stack
{
Cont<T> _container; //here you use `T` as template argument to `Cont`
Cont<int> _ints; //you can do even this if you need a containter of int.
//though in this case you don't need this.
public:
void push(T const & data)
{
_container.push_back(data);
}
//etc
};
答案 1 :(得分:0)
要使模板即时化,需要定义。在您的示例中,您只提供模板声明,不够,以便进行即时处理。该定义给出了详细说明如何使用模板参数的实现。例如,
template <typename T, template <typename> class Cont>
class Stack : Cont<T>
{
typedef Cont<T> my_container;
public:
using my_container::push_back;
/* more details here */
};
Stack<int,List> aStack1;
Stack<std::string,Deque> aStack2;
实现aStack1
源自List<int>
和astack2
,源自Deque<std::string>
。