模板类编译错误。不识别创建的类

时间:2016-02-13 12:48:09

标签: c++ templates compilation friend

我有2个编译时间错误。这是我的课程定义和实现

#ifndef QUEUE_H
#define QUEUE_H

#include <iostream>
#include "MyException.h"

using namespace std;

template<class T>
class Queue;

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

template<class T>
class Queue
{
    public:
        friend ostream& operator<< <T>(ostream&,Queue<T>&);
        Queue();
        Queue(const Queue<T>& other);
        Queue<T>& operator=(const Queue<T>& other);

        /*The destructor*/
        ~Queue();
        void enqueue(const T& el);
        T dequeue(
        void increasePriority(const T& el);
        bool isEmpty();

    private:
        /*The node class.*/
        class Node
        {
            public:
                Node(const T& data, Node* n = 0)
                {
                    element = data;
                    next = n;
                }

                T element;
                Node* next;
        };

        /*The head of the queue*/
        Node* head;

};

#include "Queue.C"

#endif

//类定义

template<class T>
Queue<T>::Queue()
{
    head = 0 ;
    head->next = 0 ;
}

template<class T>
Queue<T>::Queue(const Queue<T>& other)
{
    other = this  ;
}

template<class T>
Queue<T>& Queue<T>::operator=(const Queue<T>& other)
{
    while(!other.isEmpty())
        other.deque() ;

    //if(other->head != 0)
    //  cout << "Empty queue" << endl ; FOR TESTING

    other->head = new Node(head->value,0) ;
    Node *temp = head->next ;
    Node *otherTemp = other->head->next;
    other->head->next = otherTemp ;
        while(temp != 0) 
        {
            otherTemp =  new Node(temp->value, 0)  ;
            temp = temp->next ;
            otherTemp = otherTemp->next ;
        }
}

template<class T>
Queue<T>::~Queue()
{
    delete head ;
    head =0 ;

}

template<class T>
void Queue<T>::enqueue(const T& el)
{
    Node *newNode  = new Node(el,head) ;
    head = newNode ;
}

template<class T>
T Queue<T>::dequeue()
{
    T store ;
    if(isEmpty())
        throw MyException("Cannot try to remove an element from a queue. Please only rempve elements when queue is not empty") ;
    else if(head->next = 0)
    {       
        store = head->value ;
        delete head  ;
        head = 0 ;
    }
    else
    {
        Node *tmp = head  ;
        Node *prev = head ;
        while(tmp->next != 0)
        {
            prev = tmp ;
            tmp = tmp->next ;
        }
        store = tmp->value ;
        prev->next  = 0 ;
        tmp->next = 0 ;
        delete tmp ; 
        tmp = 0 ;
    }

    return store ;
}

template<class T>
bool Queue<T>::isEmpty()
{
    return (head == 0) ;
}

template<class T>
void Queue<T>::increasePriority(const T& el)
{
        if(!(head-> value == el) )
    {
        Node *tmp, *prev = head ;
        while(tmp != 0 || !(tmp->value == el))
        {
            prev = tmp ;
            tmp = tmp->next ;
        }
        if(tmp != 0)
        {
            T store = tmp->value ;
             tmp -> value = prev->value ;
            prev->value = store ;
        }       
    }
}

template<class T>
ostream& operator<<(ostream& os,Queue<T>& queue)
{
    return os :
}

第一个错误看起来像这样

\Queue.C:4:1: error: 'Queue' does not name a type
 Queue<T>::Queue()
 ^
\Queue.C:11:1: error: 'Queue' does not name a type
 Queue<T>::Queue(const Queue<T>& other)
 ^
\Queue.C:17:1: error: 'Queue' does not name a type
 Queue<T>& Queue<T>::operator=(const Queue<T>& other)
 ^
\Queue.C:38:1: error: 'Queue' does not name a type
 Queue<T>::~Queue()
 ^
\Queue.C:46:11: error: expected initializer before '<' token
 void Queue<T>::enqueue(const T& el)
           ^
\Queue.C:53:8: error: expected initializer before '<' token
 T Queue<T>::dequeue()
        ^
\Queue.C:84:11: error: expected initializer before '<' token
 bool Queue<T>::isEmpty()
           ^
\Queue.C:90:11: error: expected initializer before '<' token
 void Queue<T>::increasePriority(const T& el)
           ^
\Queue.C:110:1: error: 'ostream' does not name a type
 ostream& operator<<(ostream& os,Queue<T>& queue)
 ^
[Finished in 1.5s]

我一直在使用g++ -c Queue.C -o Queue.o

进行编译

第二个问题是与朋友班有关。由于os流操作符的重载是一个友元类,当我编写它的实现时,即:ostream& operator<<(ostream& os,Queue<T>& queue){}我将能够访问在Queue类中定义的Node类的私有成员变量

1 个答案:

答案 0 :(得分:2)

  

我一直在使用g++ -c Queue.C -o Queue.o

进行编译

看起来错误是因为Queue.C不包含Queue.h所以文件的第一行是指编译器从未听说过的类模板,因为它还没有看到声明。

但那仍然不起作用。

类模板不是类,你不能像那样编译它。

模板仅在实例化时才有用,因此编译器使用模板生成具体类。因此,您可以编译使用Queue<int>Queue<std::string>的代码,但您不能只编译Queue<T>,因为这只是用于生成类的模板

您需要编译使用Queue的文件,并且对于该文件,能够为实例化的类生成代码,它需要能够查看模板的完整定义,因此您需要定义标题中的所有内容。

所以完全摆脱Queue.C,将所有代码放在Queue.h中,然后你将有一个定义工作类模板的头文件。现在,您可以将该头文件包含在其他.C文件中,并使用该模板执行一些有用的操作。