-1

I am having a 2 compilation time error. Here is my class definition and implemetation

#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

// Class definitions

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 :
}

The first error looks like this

\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]

I've been compiling it using g++ -c Queue.C -o Queue.o

The second question is to do with friend classes. Since the overloading of the os stream operator is a friend class, when I write its implementation ie: ostream& operator<<(ostream& os,Queue<T>& queue){} will I be able to access the private member variables of the Node class defined within the Queue class

Keaton Pennells
  • 189
  • 2
  • 4
  • 15
  • 3
    You shouldn't compile `Queue.C`. You should only compile some code that uses `#include "Queue.h"`. – juanchopanza Feb 13 '16 at 12:49
  • I only compiled the my main file which #includes 'Queue.C' and i still receive the same errors – Keaton Pennells Feb 13 '16 at 12:55
  • That is because you didn't do what I said! Read my previous comment carefully. – juanchopanza Feb 13 '16 at 12:56
  • 1
    `ostream& o` In addition, you should really include the correct headers and prepend `std::` on those items. Also, `using namespace std;` should not be in a header file. – PaulMcKenzie Feb 13 '16 at 12:57
  • 1
    You need include "Queue.h" to your file, not "Queue.C" – ALEXANDER KONSTANTINOV Feb 13 '16 at 13:00
  • The error comes from line 4, but in your example that is the first line. You are not showing us the whole file. – Jonathan Wakely Feb 13 '16 at 13:07
  • Thank you for all the answers. I have gotten it to compile but as soon as i run the main executable an error dialogue boxs appears informing me "main.exe" has stopped working – Keaton Pennells Feb 13 '16 at 13:53
  • @KeatonPennells Your initial question of why it doesn't compile was answered. Running the program is a different issue, which should be a new post. Also, post `main` if you are going to start a new question, as that is what will be required to determine what the issue is. – PaulMcKenzie Feb 13 '16 at 18:10

1 Answers1

2

I've been compiling it using g++ -c Queue.C -o Queue.o

It looks like the errors are because Queue.C doesn't include Queue.h so the first line of the file is referring to a class template the compiler has never heard of, because it hasn't seen the declaration.

But that's still not going to work.

A class template is not a class, you can't just compile it like that.

A template is only useful when you instantiate it, so that the compiler uses the template to generate a concrete class. So you could compile code that uses Queue<int> or Queue<std::string>, but you can't just compile Queue<T> because that is just a template for generating classes.

You need to compile a file that uses Queue, and for that file to be able to generate the code for the instantiated class it needs to be able to see the full definition of the template, so you need to define everything in the header.

So get rid of Queue.C completely, put all that code in Queue.h, then you will have a header file that defines a working class template. Now you can include that header file in some other .C file and use the template to do something useful.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521