2

我正在阅读现代 C++ 设计,但无法完全理解模板模板参数的工作原理。

例如,如本文http://www.informit.com/articles/article.aspx?p=376878中给出的, 我们可以使用类型和容器的模板参数创建一个堆栈。

如果我们只使用类型和容器作为模板 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????
4

2 回答 2

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
};
于 2013-01-02T11:03:58.297 回答
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从 a派生List<int>astack2从 a 派生的实现Deque<std::string>

于 2013-01-02T11:04:32.050 回答