I'm currently writing a templated queue class and I am running into some issues with overloading the << stream operator. When I go to compile it in gcc, I get the following errors.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
queue.h:65: warning: friend declaration `std::ostream& operator<<(std::ostream&, queue<T>&)' declares a non-template function
queue.h:65: warning: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here) -Wno-non-template-friend disables this warning
In file included from queue.h:76,
from queueApp.cpp:8:
queue.cpp: In function `std::ostream& operator<<(std::ostream&, queue<T>&)':
queue.cpp:164: error: `node' was not declared in this scope
queue.cpp:164: error: `nodePtr' was not declared in this scope
queue.cpp:166: error: `front' was not declared in this scope
queue.h:65: warning: friend declaration `std::ostream& operator<<(std::ostream&, queue<T>&)' declares a non-template function
queue.h:65: warning: (ifthis is not what you intended, make sure the function template has already been declared and add <> after the function name here) -Wno-non-template-friend disables this warning
In file included from queue.h:76:
queue.cpp: In function `std::ostream& operator<<(std::ostream&, queue<T>&)':
queue.cpp:164: error: `node' was not declared in this scope
queue.cpp:164: error: `nodePtr' was not declared in this scope
queue.cpp:166: error: `front' was not declared in this scope
I feel like I am trying to use the overloaded stream in a way that it was not meant to be used. However, I'm not sure what the proper way to it would be.
#include <iostream>
usingnamespace std;
#ifndef QUEUE_H
#define QUEUE_H
template <class T>
class queue
{
private:
// The class for storing all the node information
class node
{
public:
node() {next = NULL;}
node(T value) {data = value; next = NULL;}
T data;
node *next;
};
// Attributes
node *front;
node *rear;
public:
// Constructor
queue() {front=NULL;rear=NULL;}
// The Big Three
// The Copy Constructor
queue(const queue &someQueue);
// The Assignment Operator
queue& operator=(const queue &rhs);
// The Destuctor that deletes all the nodes in the queue
~queue();
// Returns true if the queue is empty
// otherwise, false
bool isEmpty();
// Removes all the items in the queue
void clear();
// Adds an item to the queue
void enqueue(T item);
// Removes an item from the queue and passes it by reference
bool dequeue(T &item);
// Returns the number of elements in the queue
int size();
// Overloading the output stream operator to allow the application
// programmer to display the queue on the screen.
friend ostream& operator <<(ostream &output, queue<T> &rhs);
};
/*
// Overloading the output stream operator to allow the application
// programmer to display the queue on the screen.
template <class T>
ostream &operator<<(ostream &output, queue<T> &rhs);
*/
#include "queue.cpp"
#endif
The easiest solution is to implement the ostream operator directly in the class declaration itself. You have to
move the entire contents of queue.cpp to the header anyway otherwise you'll end up with linker errors.
I had considered that; however, I've always been taught to write my class prototypes and member functions in different files. It seems (to me at least) to be easier to read and pick out problems in individual function.
Except that with templates, you don't have that option. You must put the definitions of the template functions/classes inside the header file, because the compiler must have access to the implementations of said functions/classes at the point of invocation/usage (ie, other .cpp files).