When building an error occurs:

#include <iostream> const int DefaultSize=10; using namespace std; template <class T> class Array { public: Array(int itsSize=DefaultSize); Array(const Array& rhs); ~Array() {delete [] pType;} Array& operator = (const Array&); T& operator[] (int offset){return pType[offset];} const T& operator [] (int offset) const {return pType[offset];} friend void Intrude(Array<int>); friend ostream& operator<< (ostream&, Array<T>&); // < Компилятор указывает на int GetSize() const {return itsSize;} //эту строку private: T *pType; int itsSize; }; template <class T> ostream& operator << (ostream& output, Array<T>& theArray) { for (int i=0;i<theArray.GetSize();i++) output<< "["<<i<<"]"<<theArray[i]<<endl; return output; } 

compile report:

g ++ -Wall -c "template.cpp" (in the directory: / host / projects / template) template.cpp: 30: 52: warning: friend declaration 'std :: ostream &> operator << (std :: ostream &, Array < t> &) 'declares a non-template function template.cpp: 30: 52: note: (you need to make it a function> The build was successful.

assembly report:

g ++ -Wall -o "template" "template.cpp" (in the directory: / host / projects / template) template.cpp: 30: 52: warning: friend declaration 'std :: ostream &> operator << (std :: ostream & , Array <t> &) 'declares a non-template function template.cpp: 30: 52: note: (if you’re not what you intended, make a function name here) /tmp/cciPebmn.o: In function main': template.cpp:(.text+0x162): undefined reference to > operator << (std :: basic_ostream <char, std :: char_traits <char = "" >> &, Array <int> &) 'collect2: ld returned 1 exit status The assembly failed with an error.

Well, actually the question: what is the mistake?

    5 answers 5

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

      I guess in the class description before

       friend ostream& operator<< (ostream&, Array<T>&); 

      need to put the template<class T> :

       template<class T> friend ostream& operator<< (ostream&, Array<T>&); 

      A friend is not a method, it is such a tricky global declaration. Accordingly, the class template does not affect it.

      I note that the friend-declaration is, in principle, superfluous, because the operator << refers only to public members.

      • one
        by We have: <precode> template.cpp: 21:15: error: declaration of 'class T' template.cpp: 5: 11: error: shadows template parm 'class T' </ precode> Therefore, in my answer I used a different name for template class :-) - gecube
      • You are right, of course. Instead of T, you need to give another name. - Peter Taran

      Instead

       friend ostream& operator<< (ostream&, Array<T>&); 

      write:

       friend ostream& operator<< <T>(ostream&, Array<T>&); 

      On gcc did not check, but should help.

      • now and on compiling an error produces: template.cpp: 30: 21: error: template-id 'operator << <int>' for 'std :: ostream & operator << (std :: ostream &, Array <int> &)' does not match any template declaration - Tomagavk
      • Interesting. Along the way, it really depends on the compiler. My version is suitable for MSVS. Then the @gecube option will probably help. - Fiztex
      • Yes indeed - Tomagavk
      • Thu, well, and the sense to use templates, if everywhere they are made differently? Along the way, it turns out that the subset of C ++, which can be safely used is not so big. And if it is completely honest, in the example that I freaked out, I do not quite understand the need to write as it is written :-) - gecube
      • Strange, but describing a function as nested in a class is an alternative way to make everything work. Those. it is enough to write in the class description: <pre> friend ostream & operator << (ostream & os, Array <T> & ar) </ * blablabla * / return os;> </ pre>, delete the separate operator function and everything starts working. - gecube

      Operator himself

       template <class T> ostream& operator << (ostream& output, Array<T>& theArray) 

      inline:

       template <class T> inline ostream& operator << (ostream& output, Array<T>& theArray) 
      • Similarly: <pre> template.cpp: 21:15: error: declaration of 'class T' template.cpp: 5: 11: error: shadows template parm 'class T' </ pre> - gecube
      • Listen, well, it's not serious at all. It is completely incomprehensible what file you have in it, but you are asking for something to be fixed by throwing errors with file names and lines without any explanations at all. Either bring the full code broken down into files and how you collect them and what errors arise in the end - or I’m afraid of a normal answer to your question you won’t get from anyone in principle. - Ander
      • This is unnecessary. See the author's source code - we make the edits you specified. We get an error. And now the question is - have you tried before advising? - gecube
      • Otozh :) g ++ --version g ++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3 normal flight. I just had to add an empty main and bang the line friend ostream & operator << (ostream &, Array <T> &); How clearly redundant and from which warnings. But with her no mistakes. What am I doing wrong? Moreover, it is natural, even with -Wall says nothing. Hence the actual questions to the author of the question. - Ander
      • Well yes. Again, it is important that <pre> template <class T> // here class Array {... template <class _T> friend ostream & operator << (ostream &, Array <_T> &); // and here ...} </ pre> the name of the template did not match. - gecube

      Here's the code, everything compiles on gcc ++ 4.4.3 and even runs. What's the question?

       ~/tmp$ g++ --version g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3 Copyright (C) 2009 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ~/tmp$ g++ template.cpp ~/tmp$ ./a.out [0]0 [1]0 [2]0 [3]0 [4]0 [5]0 [6]0 [7]0 [8]0 [9]0 

      template.cpp:

       #include <iostream> const int DefaultSize=10; using namespace std; template <class T> class Array { public: Array(int s=DefaultSize) : itsSize(s), pType( new T[s] ) {} Array(const Array& rhs); ~Array() {delete [] pType;} Array& operator = (const Array&); T& operator[] (int offset){return pType[offset];} const T& operator [] (int offset) const {return pType[offset];} friend void Intrude(Array<int>); template <class _T> friend ostream& operator<< (ostream&, Array<_T>&); // < Компилятор указывает на int GetSize() const {return itsSize;} //эту строку private: T *pType; int itsSize; }; template <class T> inline ostream& operator << (ostream& output, Array<T>& theArray) { for (int i=0;i<theArray.GetSize();i++) output<< "["<<i<<"]"<<theArray[i]<<endl; return output; } int main() { Array<double> xxx; cout << xxx << endl; return 0; }