-3

i have tried everything , i can't understand why it's not working.

g++ throw :

Queue.H:53: error: declaration of âoperator<<â as non-function

Queue.H:53: error: expected â;â before â<â token

Queue.H:59: error: expected â;â before âprivateâ

the code is:

#ifndef _Queue_H_
#define _Queue_H_
#include <iostream>
#include <string>
using namespace std;

template <class T, int size>

class Queue
{
public:
    Queue():_Num(0){
        T Arr=new T[size];
        for(int i=0;i<size;i++)
            Arr[i]=0;}
    ~Queue(){
        for (int i=0;i<_Num;i++)
            delete Arr_[i];
        delete [] Arr_;
    }
    bool IsEmpty() const{return !_Num ;}
    bool IsFull() const{return (_Num==size);}
    void count() const{return _Num;}
    T& Top() const {
        if(!IsEmpty())
            return Arr_[0];
        else
            throw("empty");
    }
    void operator << (const T & item ) {
        if(!IsFull()){
            Arr_[_Num+1]=item;
            _Num++;}
        else
            throw("full");}
    
    T  operator >> (T & item) {
        if(IsEmpty())
            throw("empty");
        
        item=Arr_[0];
        delete Arr_[0];
        for(int i=1;i<_Num;i++)
            Arr_[i-1]=Arr_[i];
        _Num--;
        return item;}
    
    T operator [] (const T &number){
        return (number<size) ?Arr_[number]:throw("overload");}
    
    friend ostream & operator << <T,size>(ostream & or ,const Queue<T,size> &a){
        for(int i=0;i<a._Num;i++)
            or<<a.Arr_[i];
        return or;
    }
    
private:
    T Arr_[size];
    int _Num;
};
Community
  • 1
  • 1
oren
  • 9

2 Answers2

3

A friend function should be defined outside, you could hit issues like Access friend function defined in class . You should just leave a friend declaration within the class and define the function outside the class.

But your error comes due to the way you name your template variables.

Instead of

friend ostream & operator << <T,size>(ostream & or ,const Queue<T,size> &a){

try just

friend ostream & operator << (ostream & or ,const Queue<T,size> &a){

p.s. _Num - Bad Idea

Community
  • 1
  • 1
Karthik T
  • 31,456
  • 5
  • 68
  • 87
  • Yeah yeah, you're both on target. sry for the cross take on terms, Karthik. totally my bad. I'll drop comment. Been a long day. – WhozCraig Jan 25 '13 at 11:21
  • Why complicate it so much? Simply say: *"friend functions are declared as friend in the class, and defined elsewhere*". IMO the important distinguishing point is *declaration* and *definition*. – Alok Save Jan 25 '13 at 11:21
  • @WhozCraig no worries, always glad to improve my c++ jargon – Karthik T Jan 25 '13 at 11:24
  • i have tried to write the friend function outside and changed what you sayed it's still not working. – oren Jan 25 '13 at 11:30
  • @oren *both* answers should work, but Karthik's is less invasive and more inline with what you were originally going for. If it works for you (and it should), then excellent. – WhozCraig Jan 25 '13 at 11:34
0

If you are concerned about tight coupling like me, you are especially concerned about friend (because that's the tightest coupling C++ has to offer). That said, there is a view of operator<< that makes it easy to implement, inside the class, without any friend declarations:

Simply put, operator<< for ostream is a mere beautification for a simple print method. And it is only because of this beautification (chaining os << a << b << c... calls) that the operator can't be a method of the class it should be part of. So many people resort to a friend declaration of that operator, which imo is an encapsulation breaking ugly workaround. So what can you do?

template <class T, int size>
class Queue
{
public:
    /**
     * Here comes the method. Inside the class, were it should be, 
     * having all the access it needs. 
     * No template-specialization-friend-declaration needed.
     */
    ostream & printToStream(ostream & or) const 
    { 
        for(int i=0;i<a._Num;i++)
            or<<Arr_[i];
        return or;
    }

private:
    T Arr_[size];
    int _Num;
};

/**
 * Here comes operator<<. It is what it really is:
 * Just a beautification, nothing more, no additional functionality.
 */
template <class T, int size> 
ostream& operator<<(ostream& os, Queue<T,size> const& q)
{ return q.printToStream(os); }

See? No big deal at all. If you do that often, and if your method is called printToStream every time, you can make it a template:

template <class Printable>
ostream& operator<<(ostream& os, Printable const& p)
{ return p.printToStream(os); }

And if you want to get fancy, you can enable_if that operator only if it has that member function. No more "friend operator<< how should I do that again?", just implement printToStream, and the beautification-operator<< already exists.

Arne Mertz
  • 24,171
  • 3
  • 51
  • 90