How to define a seperate implementation of a template class constructor

139 Views Asked by At

I am working with an old code in C++ that uses a custom implementation of a matrix class.

The matrix is class is implemented as a template class. The declaration looks like this

/**********************************************************************/
/*** TMatrix private **************************************************/
/**********************************************************************/
//
template <class X> class TMatrix {

private :

long min_adr_row; 
long max_adr_row; 


/**********************************************************************/
/*** TMatrix public ***************************************************/
/**********************************************************************/
//
public:
   
long     row;                        
long     col;                        

X     **data;                        


 TMatrix<X> (const long & m = 0,              /*** Konstruktor      ***/
             const long & n = 0);
 TMatrix<X> (const TMatrix<X> & A);           /*** Copy-Konstruktor ***/
~TMatrix<X> (void);                           /*** Destruktor       ***/


/**********************************************************************/
/*** overloaded operators *******************************************/
/**********************************************************************/
//
X *        & operator [] (const long & index)   const; /*** []      ***/
TMatrix<X> & operator =  (const TMatrix<X> & A);       /***  =      ***/

TMatrix<X>   operator +  (const TMatrix<X> & A) const; /*** C = A+B ***/
TMatrix<X>   operator -  (const TMatrix<X> & A) const; /*** C = A-B ***/
TMatrix<X>   operator *  (const TMatrix<X> & A) const; /*** C = A*B ***/

TMatrix<X> & operator += (const TMatrix<X> & A);       /*** B = B+A ***/
TMatrix<X> & operator -= (const TMatrix<X> & A);       /*** B = B-A ***/
TMatrix<X> & operator *= (const TMatrix<X> & A);       /*** B = B*A ***/

TMatrix<X>   operator *  (const double a)       const; /*** B = A*a ***/
int          operator == (const TMatrix<X> & A) const; /*** B == A  ***/

// ... other methods

};

This code is contained in the header file TMatrix.h.

The implementations are contained in the same header file. I am getting an error in the definition of the first constructor that currently looks like this:

template <class X> TMatrix<X>::TMatrix<X>(const long & m, const long & n) {


// .. do stuff where 'data' and 'X' are used


return;
}

The project previously ran with C++ 11 where that code compiled without errors.

However with newer C++ versions this code throws various errors (does not compile) depending on the different versions.

For example under C++ 14 I am getting the compiler error C2988 unrecognizable template declaration/definition.

I suspect that there is something inherently wrong with the definition of this constructor and/or possibly with the declaration of the class itself.

I tried to replace the first line of the definition with

template <class X> TMatrix(const long & m, const long & n) {

which seems more logical to me but it gives the Syntax error: "deduction guide cannot be defined".

I also don't understand why the template keyword has to be used in the constructor definition but not in its declaration within the class.

I am considering now to simply replace this template constructor with two separate "normal" constructors for int and double which are the only types that this class is being used with in the code. But I still want to understand what caused this error and why it works fine in C++ 11.

Hope someone can help, thanks.

1

There are 1 best solutions below

1
TartanLlama On

The definition for the constructor should only have template arguments on the part before the double colon:

template <class X> 
TMatrix<X>::TMatrix(const long & m, const long & n) {
    // .. do stuff where 'data' and 'X' are used
    return;
}

Clang tells you this in its error:

<source>:49:32: error: out-of-line constructor for 'TMatrix' cannot have template arguments
   49 | template <class X> TMatrix<X>::TMatrix<X>(const long & m, const long & n) {
      |