0

I am new to C++ and got this error for hours and I hope someone can help me with this.

So basically I have got 2 classes: Matrix,DenseMatrix with DenseMatrix being the subclass of Matrix.


For some simple mathematical operations like adding two matrices which are always the same for any type of matrix, I wanted to implement a function in the class Matrix.

T &mul(const Matrix &other);

The idea is that calling mul on a subclass (e.g DenseMatrix), the result will also be a DenseMatrix. However the other matrix does not need to be the same class, just any subclass of Matrix. That's why I use generic types and my classes are defined like this:

class DenseMatrix : public Matrix<DenseMatrix>
class OtherMatrix: public Matrix<OtherMatrix>
class OtherMatrix2: public Matrix<OtherMatrix2>
...

So that calling mul will return a matrix of the same type and the argument is simply a Matrix without diamond-brackets.

Now the Problem is that I am getting the following error:

DenseMatrix mat{6,6};
DenseMatrix mat2{6,6};
mat.add(mat2);

>>> undefined reference to `Matrix<DenseMatrix>::add(Matrix<DenseMatrix> const&, int)'

I was thinking that maybe I need to introduce a second generic type for the argument of the function but I am not sure how to do this.

I am very happy if someone could help me with this one.


Matrix.h:

template <typename T>
class Matrix {
    T &add(const Matrix &other, int threads = 1);
}

Matrix.cpp:

#include "Matrix.h"
template<typename T>
T &Matrix<T>::add(const Matrix &other, int threads) {
    std::cout << "ADDING";
    return *this;
}

DenseMatrix.h:

class DenseMatrix : public Matrix<DenseMatrix> {


}
Finn Eggers
  • 857
  • 8
  • 21
  • yes that could be! thank you – Finn Eggers Nov 19 '19 at 20:09
  • actually I checked. No it is not the same. I am dealing with subclasses. It does work when I put the impementation into the header file but not when I put it into the .cpp file – Finn Eggers Nov 19 '19 at 20:13
  • "It does work when I put the impementation into the header file but not when I put it into the .cpp file" - The duplicate question (answers for it) explains the reason of that. What else do you want from us? – Tsyvarev Nov 20 '19 at 00:19
  • The problem does not come up because of the generic type but because of the subclass. And that is not explained in the other answer – Finn Eggers Nov 20 '19 at 05:50
  • The line `class DenseMatrix : public Matrix` actually does three things: 1. It *declares* the class `DenseMatrix`. 2. It instantiates the template `Matrix` with parameter `DenseMatrix`. 3. It *defines* the class `DenseMatrix` as a subclass of the instantiated template `Matrix`. You think your problem is because of the 3d step (defining a *subclass*). But look into the error message: It is solely about `.add` method in instantiated `Matrix` template. The **declaration** of the method is taken from `Matrix.h` *header*, but its **definition** is missing. – Tsyvarev Nov 20 '19 at 08:21
  • But why does it not take the implementation in the .cpp file? – Finn Eggers Nov 20 '19 at 08:22
  • `Matrix.cpp` is **compiled** into the object file and only then used by the linker along with the object file compiled from `DenseMatrix.cpp`. The compiled code doesn't contains a *text* which shows the linker how to instantiate a template method with given template parameter. The compiled code may only contain **instantiated** methods. But your `Matrix.cpp` doesn't *instantiate* any method. See [that answer](https://stackoverflow.com/a/16493574/3440745) for the duplicate question for more detailed description. – Tsyvarev Nov 20 '19 at 08:36

0 Answers0