【问题标题】:Template class compilation error. Not recognising class created模板类编译错误。不识别类创建
【发布时间】:2016-02-13 12:48:09
【问题描述】:

我遇到了 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&amp; operator&lt;&lt;(ostream&amp; os,Queue&lt;T&gt;&amp; queue){}时,我将能够访问队列类中定义的Node类的私有成员变量

【问题讨论】:

  • 你不应该编译Queue.C。你应该只编译一些使用#include "Queue.h"的代码。
  • 我只编译了我的主文件#includes 'Queue.C',我仍然收到同样的错误
  • 那是因为你没有按照我说的去做!仔细阅读我之前的评论。
  • ostream&amp; o 此外,您应该真正包含正确的标题并在这些项目上添加std::。另外,using namespace std; 不应该在头文件中。
  • 您需要在文件中包含“Queue.h”,而不是“Queue.C”

标签: c++ templates compilation friend


【解决方案1】:

我一直在用g++ -c Queue.C -o Queue.o编译它

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

但这仍然行不通。

类模板不是类,不能就这样编译。

模板仅在实例化时才有用,以便编译器使用模板生成具体类。所以你可以编译使用Queue&lt;int&gt;Queue&lt;std::string&gt;的代码,但你不能只编译Queue&lt;T&gt;,因为那只是一个模板用于生成类。

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

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

【讨论】:

    猜你喜欢
    • 2020-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多