title: C++ second template in single template class
body: <p>I am developing a matrix class for my personal library. I am using a template class (Class T) because I want a matrix to be of any numeric or boolean format (and don't want to retype everything). So what I would like to do is have the operater+= allow a scalar or a matrix. However,  I would like to be able to add two matrices together regardless of their numeric format (Class U). </p>
  
  <p>I get the following compile errors.</p>
  
  <pre><code>error: prototype for 'JecMatrix&lt;T&gt;&amp; JecMatrix&lt;T&gt;::operator+=(const JecMatrix&lt;U&gt;&amp;)' does not match any in class 'JecMatrix&lt;T&gt;'
  error: candidates are: template&lt;class T&gt; template&lt;class U&gt; JecMatrix&amp; JecMatrix::operator+=(const U&amp;)
  error:                 template&lt;class T&gt; template&lt;class U&gt; JecMatrix&amp; JecMatrix::operator+=(const JecMatrix&lt;U&gt;&amp;)
  </code></pre>
  
  <p>Does anyone have a solution to this? I've included the entire class below.</p>
  
  <pre><code>#ifndef JECMATRIX_H
  #define JECMATRIX_H
  
  #include &lt;typeinfo&gt;
  
  #include &lt;QTime&gt;
  #include &lt;QList&gt;
  
  #include &lt;JecLibrary_global.h&gt;
  #include &lt;JecUtils.h&gt;
  
  template&lt;class T&gt;
  class JECLIBRARYSHARED_EXPORT JecMatrix
  {
  public:
      JecMatrix();
      JecMatrix(const int&amp; rows, const int&amp; cols);
      JecMatrix(const QList&lt;QList&lt;T&gt; &gt;&amp; sourceMatrix);
  
      ~JecMatrix();
  
      JecMatrix&lt;T&gt;&amp; operator=(const JecMatrix&lt;T&gt;&amp; rhs);
      bool operator!=(const JecMatrix&lt;T&gt;&amp; rhs) const;
      bool operator==(const JecMatrix&lt;T&gt;&amp; rhs) const;
  
      template&lt;class U&gt; JecMatrix&lt;T&gt;&amp; operator+=(const JecMatrix&lt;U&gt; &amp;rhs) throw(QString);
      template&lt;class U&gt; JecMatrix&lt;T&gt;&amp; operator+=(const U&amp; rhs) throw(QString);
  
  };
  
  template&lt;class T&gt;
  JecMatrix&lt;T&gt;::JecMatrix()
  {
      T var;
      assertNumber(var);
  }
  
  template&lt;class T&gt;
  JecMatrix&lt;T&gt;::JecMatrix(const int &amp;rows, const int &amp;cols)
  {
      for (int r = 0; r &lt; rows; ++r)
      {
          matrix.append(QList&lt;T&gt;());
          for (int c = 0; c &lt; cols; ++c)
          {
              matrix[r].append(0);
          }
      }
  }
  
  template&lt;class T&gt;
  JecMatrix&lt;T&gt;::JecMatrix(const QList&lt;QList&lt;T&gt; &gt;&amp; sourceMatrix)
  {
      for (int r = 0; r &lt; sourceMatrix.length(); ++r)
      {
          matrix.append(QList&lt;T&gt;());
          for (int c = 0; c &lt; sourceMatrix.at(r).length(); ++c)
          {
              matrix[r].append(sourceMatrix.at(r).at(c));
          }
      }
  }
  
  template&lt;class T&gt;
  JecMatrix&lt;T&gt;&amp; JecMatrix&lt;T&gt;::operator=(const JecMatrix&lt;T&gt;&amp; rhs)
  {
      if (this == &amp;rhs)
      {
          return *this;
      }
  
  
      this-&gt;id = rhs.id;                          // The id of the Base.
  
      this-&gt;minerals = rhs.minerals;              // The minerals available at that base.
      this-&gt;vespene = rhs.vespene;                        // The gas available at that base.
  
      this-&gt;buildings = rhs.buildings;            // The units the player owns during this second. The outer QList holds the types of units and the inner holdes the unique coppies of that unit.
      this-&gt;units = rhs.units;                    // The units the player owns during this second. The outer QList holds the types of units and the inner holdes the unique coppies of that unit.
  
      return *this;
  }
  
  
  template&lt;class T,class U&gt;
  JecMatrix&lt;T&gt;&amp; JecMatrix&lt;T&gt;::operator+=(const JecMatrix&lt;U&gt; &amp;rhs) throw(QString)
  {
      // Perform type checking.
      U var;
      assertNumber(var);
  
      // Perform size checking.
      if (rhs.getRows() != getRows()) {
          throw ("To add the matrices they must have the same number of rows and columns.  Matrix a has "
                      + QString::number(a.getRows())
                      + " rows and matrix b has "
                      + QString::number(b.getRows()) + " rows.");
      }
  
      if (rhs.getCols() != getCols()) {
          throw ("To add the matrices they must have the same number of rows and columns.  Matrix a has "
                      + QString::number(a.getCols())
                      + " cols and matrix b has "
                      + QString::number(b.getCols()) + " cols.");
      }
  
      double result[][] = new double[a.getRows()][a.getCols()];
  
      // Add the matrices.
      for (int resultRow = 0; resultRow &lt; a.getRows(); resultRow++) {
          for (int resultCol = 0; resultCol &lt; a.getCols(); resultCol++)
          {
              matrix[resultRow][resultCol] += rhs.matrix[resultRow][resultCol];
          }
      }
  
      return *this;
  }
  
  template&lt;class T, class U&gt;
  JecMatrix&amp; JecMatrix::operator+=(const U&amp; rhs) throw(QString)
  {
      // Perform type checking.
      U var;
      assertNumber(var);
  
      // Perform the scalar addition.
      for (int r = 0; r &lt; matrix.length(); ++r)
      {
          for (int c = 0; c &lt; matrix.at(0).length(); ++c)
          {
              matrix[r][c] += rhs;
          }
      }
  }
  
  
  #endif // JECMATRIX_H
  </code></pre>
  
  <p>Edit: removed irrelevant code.</p>