2013-03-23 108 views
0

的隐式实例下面是一个模板(队列),我试着写:未定义模板

#include <iostream> 

using namespace std; 

template <typename T> 
class Queue 
{ 
    friend ostream& operator<< (ostream &, const Queue<T> &); 
private: 
    template<class> class Node; 
    Node<T> *front; 
    Node<T> *back; 
public: 
    Queue() : front(0), back(0) {} 
    ~Queue(); 
    bool Empty() 
    { 
     return front == 0; 
    } 
    void Push(const T& NewEl) 
    { 
     Node<T&> *El = new Node<T> (NewEl); 
     if (Empty()) 
      front=back=El; 
     else 
     { 
      back-> next = El; 
      back = El; 
     } 
    } 
    void Pop() 
    { 
     if (Empty()) 
      cout << "Очередь пуста." << endl; 
     else 
     { 
      Node<T> *El = front; 
      front = front -> next; 
      delete El; 
     } 
    } 
    void Clear() 
    { 
     while (! Empty()) 
      Pop(); 
    } 
}; 

template <typename T> 
class Node 
{ 
    friend class Queue<T>; 
public: 
    Node() {next = 0;} 
    Node(T nd) {nd=node; next=0;} 
    T& getsetnode(){return node;} 
    Node<T>*& getsetnext(){return next;} 
private: 
    T front; 
    T back; 
    T node; 
    Node<T> *next; 
}; 

template <class T> ostream& operator<< (ostream &, const Queue<T> &); 

int main() 
{ 
    Queue<int> *queueInt = new Queue<int>; 
    for (int i = 0; i<10; i++) 
    { 
     queueInt->Push(i); 
     cout << "Pushed " << i << endl; 
    } 
    if (!queueInt->Empty()) 
    { 
     queueInt->Pop(); 
     cout << "Pop" << endl; 
    } 
    queueInt->Front(); 
    queueInt->Back(); 
    queueInt->Clear(); 
    cout << "Clear" << endl; 
    return 0; 
} 

在这些线路:

Node<T&> *El = new Node<T> (NewEl); 

    front = front -> next; 
    delete El; 

我得到Implicit instantiation of undefined template 'Queue<int>::Node<int>'。我究竟做错了什么?在阅读this post后,我试着将int更改为const int,看看是不是这个问题,但显然不是,因为我得到了同样的错误。

我使用XCode与LLVM编译器4.2。当我切换到GCC我得到更多的错误:

template<class> class Node;得到Declaration of 'struct Queue<int>::Node<int>'Node<T&> *El = new Node<T> (NewEl);得到Invalid use of incomplete type, 和任何与什么萨尔瓦多分配处理不能转换<int&>*<int>*(但删除引用不会改变任何东西LLVM)。

回答

2
template <typename T> 
class Queue 
{ 
private: 
    template<class> class Node; 
/* ... */ 

这是Queue::Node的前向声明。后者定义的class Node位于全局名称空间中,因此它们不相同,并且Queue::Node的任何用法都将导致不完整类型的错误。由于您不提供与内部节点的接口,因此只需取消Node的全局定义并将其粘贴到Queue

template <typename T> 
class Queue 
{ 
private: 
    class Node 
    { 
    public: 
    Node() {next = 0;} 
    /* ... */ 
    }; 
/* ... */ 
}; 
template <typename T> 
class Queue 
{ 
private: 
    class Node 
    { 
    public: 
    Node() {next = 0;} 
    /* ... */ 
    }; 
/* ... */ 
};