First, that template function definition belongs in the header file that gets pulled in wherever it's needed with #include "algebra.h"
.
The reason you're getting problems with this particular setup is that, as several comments have suggested, you're compiling the .cpp file that contains that template function definition. When the compiler compiles "algebra.cpp", it first sees the #include
directive at the top of the file, and pulls in the text from "algebra.h". That's fine as far as it goes, but at the end of "algebra.h" it sees #include "algebra.cpp"
. So it pulls in the text from there.
Now it's compiling "algebra.cpp" inside of "algebra.cpp". The include guard in "algebra.h" works here, so there is no redefinition of the contents of "algebra.h". And then it sees the definition of Matrix<rows, cols>::Matrix()
. Still okay, so far.
Now it comes to the end of the code that comes in through the #include
directive, so it continues to compile the code in "algebra.cpp", and it again sees the definition of Matrix<rows, cols>::Matrix()
, and that's the redefinition that the compiler is complaining about.
That's why you shouldn't do that.
Some folks like to put definitions of member functions of class templates in a separate file from the header that defines the class template. That's okay, but don't compile that file; it should only be compiled as part of the header that uses it. And as a practical matter, that means giving it an extension that makes it clear that it's not a source file to be compiled on its own. When I've used that approach, I use ".inl" as the extension. If you change the name of "algebra.cpp" to "algebra.inl" and make sure that you're not telling the compiler to compile "algebra.inl" this problem should go away.