Important Update: Removing the delegation of friend solved the problem Partially but why? and how may I keep it as friend...
Why the following code gets me linker error?
Dimensions dims2(3 ,14);//Fixed class 100% the bug isn't cause by it
Matrix<int> mat_2(dims2, 5);
std::cout << mat_2;
My class:
template<class T>
class Matrix {
public:
friend std::ostream &operator<<(std::ostream &os, const Matrix<T> &matrix);
;}
in .h
file I have:
template<typename T>
std::ostream &operator<<(std::ostream &os, const Matrix<T> &matrix) {}
I get the following:
Undefined symbols for architecture x86_64:
"mtm::operator<<(std::__1::basic_ostream >&, mtm::Matrix const&)", referenced from: _main in main.cpp.o ld: symbol(s) not found for architecture x86_64clang: error: linker command failed with exit code 1 (use -v to see invocation)
friend std::ostream &operator<<(std::ostream &os, const Matrix<T> &matrix);
This declares a non-template function named operator<<
(in the namespace enclosing Matrix
definition). That function is never defined. In addition, a function template also named operator<<
is defined. When doing overload resolution, the compiler prefers a non-template over the template, then the linker discovers there's no definition.
There are several ways to resolve this. One is to define the operator in-class:
template<class T>
class Matrix {
friend std::ostream& operator<<(std::ostream& os, const Matrix<T>& matrix) {
// Implementation here
}
};
Another is to befriend the function template:
template <typename T> class Matrix;
template<typename T>
std::ostream &operator<<(std::ostream &os, const Matrix<T> &matrix);
template<class T>
class Matrix {
friend std::ostream& operator<< <T>(std::ostream &os, const Matrix<T> &matrix);
};
Yet third is to not require friendship at all, e.g. like this:
template<class T>
class Matrix {
public:
// Actual implementation here.
void PrintMe(std::ostream &os);
};
template<typename T>
std::ostream &operator<<(std::ostream &os, const Matrix<T> &matrix) {
matrix.PrintMe(os);
return os;
}