在成员变量中声明时,模板typename重用

时间:2016-07-21 20:57:55

标签: c++ class templates

假设我有以下代码:

template<typename T>
struct Task
{
    T* item;
    Task* next;
    int priority;
};

class PriorityQueue
{
    public:
        PriorityQueue();
        Enqueue(T* item, int priority);
        T* Dequeue();

    private:
        Task<T>* head;

};

上面的代码将抛出编译错误,其中 T未在PriorityQueue类中声明。如果我想引用在任务结构中定义为模板类的T *项,那么这样做的正确语法是什么?

3 个答案:

答案 0 :(得分:1)

T没有特殊意义。必须使用语法template<typename T>或其变体将每个模板类或模板方法声明为模板。在这种情况下,两个T将不会自动相同。

使用模板类时,需要使用语法classname<SomeType>指定模板参数。正如@Antonio Garrido指出的那样;在您的情况下,这可能意味着您的主管成员应该被声明为Task<T>* head;

现在,由于Task似乎不是接口的一部分,您也可以将它声明为PriorityQueue类的一部分。那样T

template<typename T>
class PriorityQueue
{    
  struct Task
  {
    T* item;
    Task* next;
    int priority;
  }

  public:
    PriorityQueue();
    Enqueue(T* item, int priority);
    T* Dequeue();

  private:
    Task* head;
};

然后使用模板类:

PriorotyQueue<int> que;
auto que = PriorotyQueue<int>(); // alternatively   
que.Engueue(3);

答案 1 :(得分:1)

我不确定1是如何工作的,除非你链接了一个名为T.的东西,并且在你的课程声明后你需要;

至于两个T是否相同,他们不是。模板的重点在于它允许您有两种类型,即#34;有点&#34;相同但有不同的类型。它们只有相同的界面。

我可以在一个程序中做这样的事情:

PriorityQueue<std::string> stringQueue;

PriorityQueue<int> intQueue;

我会有两种不同类型的队列。 stringQueue的类型为PriorityQueue<std::string>intQueue的类型为PriorityQueue<int>。这些实际上是共享相同接口的不同类型,因为C ++编译器将为每个接口编译两个不同的二进制文件。如果我做了类似的事情:

intQueue.enqueue(5, 0);
stringQueue.enqueue("hello world", 1);

然后stringQueue将包含Task类型的Task<string>,因为当PriorityQueue<std::string>::enqueue创建新的Task时,它会生成Task<std::string并且与intQueue和整数相同。

T只是一个传统的变量,但你也可以做这样的模板:

template<typename Type>
template<typename A>       //these two are basically the same as T
template<Task SpecialTask> //here SpecialTask would have to be a 
                           //Task or a child of Task
template<class C>          //C must be a class
template<typename T, U, V> //here are three templates in one declaration
template<PriorityQueue PQ,
         Task T,
         typename U>       //three of different "lineage"

那么编译器如何知道PriorityQueue<int>应该具有Task<int>属性?当它注意到它有一个模板属性,或者它正在新建一个模板时,就会发生这种情况,如果它没有任何已经存在的话,它会编译Task<int>的二进制文件。

答案 2 :(得分:0)

最后一行是

Task<T>* head;

顺便说一下,你需要添加';'结束结构/类定义