friend ostream in template

Can somebody tell me why this doesn't work?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include <iostream>
using namespace std;
const int DefaultSize=10;
class xBoundary {};

template <class T>
class Array
{
      public:
             //konstruktori
             Array(int size=DefaultSize);
             Array(const Array & rhs);
             ~Array() { delete [] pType; }
             
             //operatori
             Array & operator=(const Array<T> &);
             T& operator[](int offset);
             const T& operator[](int offset) const;
             
             //funkcije pristupa
             int GetSize() const { return itsSize; }
             
             //prijateljske funkcije
             friend ostream & operator<< <>(ostream &, const Array<T> &);
             
             //definisanje klase izuzetka
             class xSize {};
             
      private:
              int * pType;
              int itsSize;
};

template <class T>
Array<T>::Array(int size):
itsSize(size)
{
             if (size<10 || size>30000)
             throw xSize();
             pType=new T[size];
             for (int i=0; i<itsSize; i++)
             pType[i]=0;
}

template <class T>
Array<T>::Array(const Array<T> & rhs)
{
                      itsSize=rhs.GetSize();
                      pType=new T[itsSize];
                      for (int i=0;i<itsSize;i++)
                      pType[i]=rhs[i];
}
                      
template <class T>
Array<T> & Array<T>::operator=(const Array<T> & rhs)
{
      if (this==rhs)
      return *this;
      delete [] pType;
      itsSize=rhs.GetSize();
      pType=new T[itsSize];
      for (int i = 0;i<itsSize; i++)
      pType[i]=rhs[i];
}

template <class T>
T& Array<T>::operator[](int offset)
{
                            if (offset>=0 && offset < GetSize())
                            return pType[offset];
                            throw xBoundary();
                            return pType[0];
}

template <class T>
const T& Array<T>::operator[](int offset) const
{
                            if (offset>=0 && offset < GetSize())
                            return pType[offset];
                            throw xBoundary();
                            return pType[0];
}

template <class T>
ostream & operator<<(ostream & output, const Array<T> & theArray)
{
        for (int i = 0; i<theArray.GetSize(); i++)
        output << "[" << i << "]" << theArray[i] << endl;
        return output;

}

int main()
{
    try
    {
          Array<int> intArray(11);
          for (int j=0; j<100; j++)
          {
              intArray[j]=j;
              cout << "celobrojni_niz[" << j << "] u redu..." << endl;
          }
    }
    catch(xBoundary)
    {
                    cout << "Nije moguce obraditi vase ulazne podatke!\n";
    }
    catch(Array<int>::xSize)
    {
                        cout << "Pogresna velicina!\n";
    }
    cout << "Kraj.\n";
    return 0;
}

When i put comments in 24th line, in declaration of class Array, everything works.
friend ostream & operator<< <>(ostream &, const Array<T> &);
But I still have ostream operator << used little before main() function.
1
2
3
4
5
6
7
8
template <class T>
ostream & operator<<(ostream & output, const Array<T> & theArray)
{
        for (int i = 0; i<theArray.GetSize(); i++)
        output << "[" << i << "]" << theArray[i] << endl;
        return output;

}

SO I dont get it what's wrong?
I would advise you to just make it inline and define it inside the class, because things get ugly otherwise:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
template <typename T>
class Array;

template <typename T>
ostream& operator<<(ostream &, const Array<T> &);

template<typename T>
class Array
{
public:
    friend ostream& operator<< <>(ostream & output, const Array<T> & theArray);
    ...
};

template<typename T>
ostream& operator<<(ostream & output, const Array<T> & theArray)
{
    ...
    return output;
}


Both the template class and the template function need to be declared before they are defined.

Of course, if you don't need the friend declaration on line 24 (you said it works without it), then get rid of it. It only needs to be a friend if it needs access to the class' private members.
Last edited on
Yes, It also worked when I deleted 24th line so then ostream function was part of class Array and not friend function, right?
Thank you for quick reply. It works now with the tips you gave me. This is just example from the book I am reading currently so that's why it has to be friend func.
Topic archived. No new replies allowed.