title: friend and template in C++
body: <p>I have a big problem in my C++ Code example. There is something wrong with 'friend' and the 'template'.<br></p>
  
  <p><strong>Error Messages:</strong><br>
  <em>Matrix.h:26:79: warning:</em></p>
  
  <blockquote>
    <p>friend declaration 'std::ostream&amp;
    matrixClass::operator&lt;&lt;(std::ostream&amp;, const matrixClass::Matrix&amp;)'
    declares a non-template function [-Wnon-template-friend]
            friend std::ostream &amp;operator&lt;&lt;(std::ostream&amp;, const Matrix &amp;matrix);</p>
  </blockquote>
  
  <p><em>Matrix.h:26:79: note:</em></p>
  
  <blockquote>
  <pre><code>  (if this is not what you intended, make sure the function template
  </code></pre>
    
    <p>has already been declared and add &lt;> after the function name here)</p>
  </blockquote>
  
  <p><em>Matrix.h:28:77: warning:</em></p>
  
  <blockquote>
  <pre><code>  friend declaration 'matrixClass::Matrix&lt;T&gt;*
  </code></pre>
    
    <p>matrixClass::operator*(const matrixClass::Matrix&amp;, const
    matrixClass::Matrix&amp;)' declares a non-template function
    [-Wnon-template-friend]
            friend Matrix* operator*(const Matrix &amp;m1, const Matrix &amp;m2);</p>
  </blockquote>
  
  <p><em>Matrix.cpp:1:0:</em></p>
  
  <blockquote>
    <p>C:\Users\Peter\CLionProjects\PK\untitled76\Matrix.h:26:79: warning:
          friend declaration 'std::ostream&amp;
    matrixClass::operator&lt;&lt;(std::ostream&amp;, const matrixClass::Matrix&amp;)'
    declares a non-template function [-Wnon-template-friend]
            friend std::ostream &amp;operator&lt;&lt;(std::ostream&amp;, const Matrix &amp;matrix);</p>
  </blockquote>
  
  <p><em>Matrix.h:26:79: note:</em></p>
  
  <blockquote>
  <pre><code>  (if this is not what you intended, make sure the function template
  </code></pre>
    
    <p>has already been declared and add &lt;> after the function name here)</p>
  </blockquote>
  
  <p><em>Matrix.h:28:77: warning:</em></p>
  
  <blockquote>
  <pre><code>  friend declaration 'matrixClass::Matrix&lt;T&gt;*
  </code></pre>
    
    <p>matrixClass::operator*(const matrixClass::Matrix&amp;, const
    matrixClass::Matrix&amp;)' declares a non-template function
    [-Wnon-template-friend]
            friend Matrix* operator*(const Matrix &amp;m1, const Matrix &amp;m2);</p>
  </blockquote>
  
  <p><em>CMakeFiles\untitled76.dir/objects.a(main.cpp.obj): In function `main':</em><br></p>
  
  <p>main.cpp:8: undefined reference to
  main.cpp:8: undefined reference to <code>matrixClass::Matrix&lt;int&gt;::Matrix(int)'&lt;br&gt;
  main.cpp:10: undefined reference to</code>matrixClass::Matrix::set(int, int, int)'<br>
  main.cpp:11: undefined reference to <code>matrixClass::Matrix&lt;int&gt;::set(int, int, int)'&lt;br&gt;
  main.cpp:12: undefined reference to</code>matrixClass::Matrix::set(int, int, int)'<br>
  main.cpp:13: undefined reference to <code>matrixClass::Matrix&lt;int&gt;::set(int, int, int)'&lt;br&gt;
  main.cpp:15: undefined reference to</code>matrixClass::operator&lt;&lt;(std::ostream&amp;, matrixClass::Matrix const&amp;)'<br>
  main.cpp:15: undefined reference to <code>matrixClass::operator&lt;&lt;(std::ostream&amp;, matrixClass::Matrix&lt;int&gt; const&amp;)'&lt;br&gt;
  main.cpp:8: undefined reference to</code>matrixClass::Matrix::~Matrix()'<br>
  main.cpp:8: undefined reference to `matrixClass::Matrix::~Matrix()'<br></p>
  
  <p><strong>Code:</strong>
  <em>Matrix.h</em></p>
  
  <pre><code>#ifndef MATRIX_H_
  #define MATRIX_H_
  
  #include &lt;iostream&gt;
  
  namespace matrixClass {
  
      template&lt;class T&gt;
      class Matrix {
      private:
          int dimension;
          T **m;
      public:
          Matrix(int d);
  
          Matrix(const Matrix &amp;original);
  
          ~Matrix();
  
          void set(int x, int y, T value);
  
          T get(int x, int y) const;
  
          int getDimension() const;
  
          friend std::ostream &amp;operator&lt;&lt;(std::ostream&amp;, const Matrix&lt;T&gt; &amp;matrix);
  
          friend Matrix&lt;T&gt;* operator*(const Matrix&lt;T&gt; &amp;m1, const Matrix&lt;T&gt; &amp;m2);
      };
  }
  
  #endif
  </code></pre>
  
  <p><em>Matrix.cpp</em></p>
  
  <pre><code>#include "Matrix.h"
  
  using namespace matrixClass;
  
  template&lt;class T&gt;
  Matrix&lt;T&gt;::Matrix(int d)
          : dimension{d}, m{new T *[d]} {
      //m = new T*[d];
  
      for (int i = 0; i &lt; d; i++) {
          m[i] = new T[d];
      }
  }
  
  // COPY-CONSTRUCTOR
  template&lt;class T&gt;
  Matrix&lt;T&gt;::Matrix(const Matrix &amp;original)
          : dimension{original.dimension},
            m{new T *[original.dimension]} {
      for (int i = 0; i &lt; dimension; i++) {
          *(m + i) = *(original.m + i);
      }
  }
  
  // DESTRUCTOR
  template&lt;class T&gt;
  Matrix&lt;T&gt;::~Matrix() {
      for (int i = 0; i &lt; dimension; i++) {
          delete[] m[i];
      }
      delete[] m;
  }
  
  template&lt;class T&gt;
  void Matrix&lt;T&gt;::set(int x, int y, T value) {
      m[x][y] = value;
  }
  
  template&lt;class T&gt;
  T Matrix&lt;T&gt;::get(int x, int y) const {
      return m[x][y];
  }
  
  template&lt;class T&gt;
  int Matrix&lt;T&gt;::getDimension() const {
      return dimension;
  }
  
  template&lt;class T&gt;
  std::ostream&amp; operator&lt;&lt;(std::ostream&amp; output, const Matrix&lt;T&gt;&amp; matrix) {
      int dimension = matrix.getDimension();
  
      for(int x = 0; x &lt; dimension; x++) {
          for(int y = 0; y &lt; dimension; y++) {
              output &lt;&lt; matrix.get(x, y) &lt;&lt; " ";
          }
          return output;
      }
  }
  
  template&lt;class T&gt;
  Matrix&lt;T&gt;* operator*(const Matrix&lt;T&gt;&amp; m1, const Matrix&lt;T&gt;&amp; m2) {
      int dimension = m1.getDimension();
      Matrix&lt;T&gt;* m = new Matrix&lt;T&gt;(dimension);
  
      for(int x = 0; x &lt; dimension; x++) {
          for(int y = 0; y &lt; dimension; y++) {
              T value = 0;
              for(int i = 0; i &lt; dimension; i++) {
                  value += m1.get(x, i) * m2.get(i, y);
              }
              m-&gt;set(x, y, value);
          }
      }
      return m;
  }
  </code></pre>
  
  <p><em>main.cpp</em></p>
  
  <pre><code>#include &lt;iostream&gt;
  #include "Matrix.h"
  
  using namespace matrixClass;
  using namespace std;
  
  int main() {
      Matrix&lt;int&gt; m(2);
  
      m.set(0, 0, 1);
      m.set(0, 1, 2);
      m.set(1, 0, 3);
      m.set(1, 1, 4);
  
      cout &lt;&lt; m &lt;&lt; "*" &lt;&lt; endl &lt;&lt; m &lt;&lt; "=" &lt;&lt; endl;
  
      return 0;
  }
  </code></pre>