I think I've run into some classic c++ pitfall and maybe some of

you guys can help me out.

For my project I will need to use matrices and vectors and so I

decided to implement them by myself. I know there are already

tons of vector and matrix implementations, but I wanted to have

one taylored for my needs and without debugging someones

else code. Also is's become somewhat personal meanwhile ;-).

The plan :

- define a Matrix<T> and a Vector<T> class

- make them friends to perform some operations directly - quick

and dirty

- define the operators processing instances of more than one type

as friends

After a while and learning a lot about c++ syntax subtleness I made

the first two steps.

Now the linker (I'm using g++ 3.3.4 without any switches refering

templates) is nagging with complaints about not knowing the friend

operators I've defined.

Lets come to the details :

I've defined both classes separated into a header and the

implementation

and for all my template classes I'm using a single .cpp file which

includes

the class template implementations to explicitly instantiate the

specialized classes.

Both header files (matrix and vector) include each other. They contain

- the forward declarations of the class templates

- the operators prototypes

- the class template itself

- including the references to friend classes and friend operators

The operators are defined in the according class implementation files.

Some more details - I will show it exemplarily :

Vector.h

================================================== =================

....

#include "Grid2D.h"

#include "Matrix.h"

namespace calcapp {

//a template method

template <class T> void doWhateveryouwant(const T& v);

//forward declaration of class template

template <class T> class Vector;

template <class T> class Matrix;

//operator prototypes

template <class T> Matrix<T> operator/ (const Vector<T>& v1, const

Vector<T>& v2);

....

//prototype of a test-method

template <class T> Vector<T> doNothing(const Vector<T>& v);

template <class T>

class Vector : public calcapp::Grid2D<T> {

public:

template <class TF> friend class Matrix;

Vector(int count_dim);

Vector(const Vector & other);

....

//tensor product

friend Matrix<T> operator/<T> (const Vector<T>& v1, const Vector<T>&

v2);

//dummy

friend Vector<T> doNothingInNS<T>(const Vector<T>& v);

protected:

....

}; //class

} //namespace

Vector.cpp

================================================== =================

#include "Vector.h"

....

namespace calcapp {

template <class T>

Matrix<T> calcapp::operator/ (const Vector<T>& v1, const Vector<T>& v2)

{

Matrix<T> result(v1.size_x, v2.size_x);

....

return result;

} //tensorproduct

....

} //namespace

TemplateInstances.cpp

================================================== =================

#include "global.h"

#include "Vector.cpp"

namespace calcapp {

template class Grid2D<fptype>;

template class Matrix<fptype>;

template class Matrix<int32>;

template class Matrix<int64>;

template class Vector<fptype>;

template class Vector<int32>;

template class Vector<int64>;

}

test.cpp

================================================== =================

....

Vector<fptype) v1(3), v2(3);

....

Matrix<fptype> M = v1/v2;

and here the compiler states :

../RunTest/test.cpp:310: undefined reference to `calcapp::Matrix<double> >calcapp::operator/<double>(calcapp::Vector<double> const&, calcapp::Vector<double> const&)'

....

================================================== =================

So what the #!@* is wrong? That was obviously a linker error and for my

understanding the compiler didn't generate code for operator/<fptype>.

Correct?

--------------------------

The problem doesn't seem to be about operators because

....

v2 = calcapp::doNothing(v1);

....

would leed to an equivalent reaction.

--------------------------

And even

....

int i = 10;

doWhateveryouwant(i);

....

won't compile (link) :undefined reference to `void calcapp::doWhateveryouwant<int>(int const&)'

So it seems it has nothing to do with classes or friends either.

But still somehow the linker figured out that the function was defined

in

the namespace calcapp.

--------------------------

Do I have to explicitly instantiate template methods too? I've

read nothing about that so far. How??

Operators?

Ok guys, what's the simple trick? ;-)

bye, Micha