friend in nested member template (in level 2)

Z

zamanbakshi

I was practicing some simple questions, and tried to create a queue in
terms of a stack (using templates). The question if simple, but I am
making a silly mistake while printing the stack. I DON'T WANT TO USE
CONTAINMENT USING TEMPLATE PARAMETERS.

The problem lays in how to print queue in terms of a stack. I get the
following error using Visual Studio 2005 (C++):

"qfrmstk.h(123) : error C2679: binary '<<' : no operator found which
takes a right-hand operand of type 'Queue<>::Stack<S>' (or there is no
acceptable conversion)"

Here is the code:-
----------------------------------------------------------
//Program to create a Queue from stack

#ifndef QFRMSTK_H
#define QFRMSTK_H

#include <iostream>
#include <exception>

struct Underflow: public std::exception {
Underflow():std::exception("Queue Undeflow."){}
};

template<typename Q=int> class Queue{
template<typename S=int> class Stack{
template<typename N=int> struct Node{
Node *next;
N info;
Node():next(0){}
Node(N inf):next(0), info(inf){}
Node(N inf, Node* nxt):next(nxt), info(inf){}
};

Node<S> *top;
public:
Stack():top(0){}
~Stack();
S Pop();
void Push(S info);
bool isEmpty() const;
template<typename U> friend std::eek:stream& operator <<
(std::eek:stream&, Stack<U>&);
//HACK: (for above operation to work)
std::eek:stream& ShowContents(std::eek:stream& strm){
if(!this->top) return strm;
typename Node<S> *current= this->top;
while(current){
strm << current->info<<' ';
current = current->next;
}
return strm;
}
};
Stack<Q> pool;
int elements;
public:
Queue():pool(),elements(0){}
//~Queue(); //not needed as pool is not a pointer
void Enqueue(Q info);
Q Dequeue();
bool isEmpty() const;
template<typename U> friend std::eek:stream& operator << (std::eek:stream&,
Queue<U>&);
};

template<typename Q> template<typename S> Queue<Q>::Stack<S>::~Stack()
{
if(!this->top) return;
typename Queue<Q>::Stack<S>::Node<S> *current = this->top;
typename Queue<Q>::Stack<S>::Node<S> *rem;
while(current){
rem = current;
current = current->next;
delete rem;
}
this->top = 0;
}

template<typename Q> template<typename S> S Queue<Q>::Stack<S>::pop(){
if(!this->top) throw Underflow();
typename Queue<Q>::Stack<S>::Node<S> *rem = this->top;
Q ret = rem->info;
this->top = this->top->next;
delete rem;
return ret;
}

template<typename Q> template<typename S> void
Queue<Q>::Stack<S>::push(S info){
try{
if(!this->top)
this->top = new typename Queue<Q>::Stack<S>::Node<S> (info);
else
this->top = new typename Queue said:
}
catch(std::bad_alloc){
std::cerr<<" out of memory.";
}
}

template<typename Q> template<typename S> bool
Queue<Q>::Stack<S>::isEmpty() const{
return !this->top;
}


// SEE THE HACK ABOVE
template<typename U> std::eek:stream& operator << (std::eek:stream& strm,
typename Queue<U>::Stack<U>& s){
if(!s.top) return strm;
typename Queue<U>::Stack<U>::Node<U> *current;
while(current){
strm << current->info;
current = current->next;
}
return strm;
}
//*/

template<typename Q> void Queue<Q>::Enqueue(Q info){
typename Queue<Q>::Stack<Q> temp;
while(!pool.isEmpty())
temp.Push(pool.Pop());
pool.Push(info);
while(!temp.isEmpty())
pool.Push(temp.Pop());
}

template<typename Q> Q Queue<Q>::Dequeue(){
return pool.Pop ();
}

template<typename Q> bool Queue<Q>::isEmpty()const{
return pool.isEmpty();
}

//////// ERROR HERE:-
template<typename U> std::eek:stream& operator << (std::eek:stream& strm,
Queue<U>& q){
//return q.pool.ShowContents(strm);
strm << q.pool;
return strm;
}

int test(){
Queue<> q;
q.Enqueue (1);
q.Enqueue (2);
q.Enqueue (3);
q.Enqueue (4);
std::cout<<q;
return 0;
}

#endif // QFRMSTK_H

Regards,
Zaman
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top