I would like to implement an Array<T>
template class. I defined the class, overloaded operator << ()
operator function for printing. Thinks seems not hard.
However, when implementing subtraction by overloading operator - ()
for two Array object, there is link error.
Both the operator << ()
and operator - ()
are declared in array.h
, declared as friend
in Array class, implemented in Array.cpp
, and "declared with specified double type"(I don't really know the correct phrase to describe it..).
Here's the code:
array.h
:
#ifndef MY_ARRAY_H
#define MY_ARRAY_H
#include <stdio.h>
#include <iostream>
template<class T>
class Array;
template<class T>
std::ostream& operator << (std::ostream& os, const Array<T>& mat);
template<class T>
Array<T> operator - (const Array<T>& A, const Array<T>& B);
template<class T>
class Array {
public:
Array(): len(0), data(NULL) {}
Array(int _len): len(_len), data(new T[len]) {
for (int i=0; i<len; i++) {
data[i] = 0;
}
}
Array(const Array& arr) = delete;
const Array& operator = (const Array&) = delete;
~Array() {
if (!data) delete[] data;
}
public:
int len;
T* data;
private:
friend std::ostream& operator << <T>(std::ostream& os, const Array<T>& arr);
friend Array<T> operator - <T>(const Array<T>& A, const Array<T>& B);
};
#endif // MY_ARRAY
array.cpp
:
#include "array.h"
#include <iostream>
template<class T>
std::ostream& operator << (std::ostream& os, const Array<T>& arr)
{
for (int i=0; i<arr.len; i++) {
os << arr.data[i] << ", ";
}
os << "\n";
return os;
}
// T=double
template
std::ostream& operator << (std::ostream& os, const Array<double>& arr);
template<class T>
Array<T> operator - (const Array<T>& A, const Array<T>& B)
{
assert(A.len==B.len && "dimension mismatch(rows)");
Array<T> C(A.rows, A.cols);
for (int i=0; i<C.len; i++) {
C.data[i] = A.data[i] - B.data[i];
}
return C;
}
// // T=double
Array<double> operator - (const Array<double>& A, const Array<double>& B);
array_test.cpp
#include "array.h"
int main()
{
Array<double> arr(4);
for (int i=0; i<arr.len; i++) {
arr.data[i] = i;
}
std::cout << arr << std::endl;
Array<double> arr2(4);
for (int i=0; i<arr2.len; i++) {
arr2.data[i] = 1;
}
std::cout << (arr2-arr) << std::endl;
return 0;
}
To compile:
clang++ array.cpp array_test.cpp
Suffers link error:
/usr/bin/ld: /tmp/array_test-c0515e.o: in function `main':
array_test.cpp:(.text+0xdc): undefined reference to `Array<double> operator-<double>(Array<double> const&, Array<double> const&)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
How do I change my code, to solve this link error?