我正在努力巩固我对模板模板参数的理解。在 C ++模板完整指南(Vandervoorde,Josuttis)中,他们在第52页上有一个示例,我想按照此图像中的说明使用:
(我也在尝试学习如何在stackoverflow上使用Picasa中的图像,所以如果上面的内容不起作用,这里有一个稍微冗长的版本)
书中的原始代码
template <typename T,
template <typename ELEM, typename ALLOC=std::allocator<ELEM> > class CONT=std::vector>
class Stack
{
private:
CONT<T > elems; //Why doesn't CONT<T, ALLOC> elems; compile?
};
不向您展示如何将其用于其他分配器。他们确实展示了一个不同的容器:
Stack<int, std::deque> my_deque_stack;
在我的天真中,我试过了:
Stack<int, std::deque<int, std::allocator<int> > > my_deque_int_stack;
我也在私人部分尝试将CONT定义为
CONT<T, ALLOC>
但这也会产生编译错误。我想知道使用Stack模板的正确语法是什么,我想使用deque但是想要指定不同的分配器。我在这里阅读了一些类似的帖子,这些帖子指示了周围的类型名称或模板限定符,我尝试了一对,但似乎无法找到神奇的公式。
答案 0 :(得分:1)
CONT中的参数定义实际上并未被编译器使用。 template-template参数CONT实际上类似于一个函数,它接受2种类型的输入并返回一个新类型:
// pseudo code
type Stack(type T, type(*CONT)(type ELEM, type ALLOC = etc)) {
return CONT(T);
}
和正常的函数指针声明一样,编译器实际上名称ELEM,ALLOC被忽略。
编译器看到的只是
template <typename T,
template <typename E, typename = std::allocator<E> > class CONT = std::vector>
struct Stack { ... };
因此,您根本无法使用ALLOC。
那么要解决它?好吧,你传递一个额外的参数!就像普通C ++函数中的情况一样:
// pseudo code
type Stack(type T, type(*CONT)(type, type), type ALLOCATOR = etc) {
// ^^^^^^^^^^^^^^^^^^^^
return CONT(T, ALLOCATOR);
}
相应的实际模板声明为
template <typename T,
template <typename, typename> class CONT = std::vector,
typename ALLOCATOR = std::allocator<T> >
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
struct Stack {
...
CONT<T, ALLOCATOR> elems;
};
//...
Stack<int, std::vector, std::allocator<int> > s;