friend and template in C++
我的C++代码示例中有一个大问题。"friend"和"template"有问题。
错误消息:矩阵.h:26:79:警告:
friend declaration 'std::ostream&
matrixClass::operator<<(std::ostream&, const matrixClass::Matrix&)' declares a non-template function [-Wnon-template-friend] friend std::ostream &operator<<(std::ostream&, const Matrix &matrix);
矩阵H:26:79:注:
1 (if this is not what you intended, make sure the function templatehas already been declared and add <> after the function name here)
矩阵.h:28:77:警告:
1 friend declaration 'matrixClass::Matrix<T>*matrixClass::operator*(const matrixClass::Matrix&, const
matrixClass::Matrix&)' declares a non-template function
[-Wnon-template-friend]
friend Matrix* operator*(const Matrix &m1, const Matrix &m2);
CPP:1:0:
C:\Users\Peter\CLionProjects\PK\untitled76\Matrix.h:26:79: warning:
friend declaration 'std::ostream&
matrixClass::operator<<(std::ostream&, const matrixClass::Matrix&)' declares a non-template function [-Wnon-template-friend] friend std::ostream &operator<<(std::ostream&, const Matrix &matrix);
矩阵H:26:79:注:
1 (if this is not what you intended, make sure the function templatehas already been declared and add <> after the function name here)
矩阵.h:28:77:警告:
1 friend declaration 'matrixClass::Matrix<T>*matrixClass::operator*(const matrixClass::Matrix&, const
matrixClass::Matrix&)' declares a non-template function
[-Wnon-template-friend]
friend Matrix* operator*(const Matrix &m1, const Matrix &m2);
cmakefilesuntitled76.dir/objects.a(main.cpp.obj):在函数"main"中:
main.cpp:8:对的未定义引用main.cpp:8:未定义的对
main.cpp:10: undefined reference to
main.cpp:12: undefined reference to
main.cpp:15: undefined reference to
main.cpp:8: undefined reference to
代码:矩阵H
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #ifndef MATRIX_H_ #define MATRIX_H_ #include <iostream> namespace matrixClass { template<class T> class Matrix { private: int dimension; T **m; public: Matrix(int d); Matrix(const Matrix &original); ~Matrix(); void set(int x, int y, T value); T get(int x, int y) const; int getDimension() const; friend std::ostream &operator<<(std::ostream&, const Matrix<T> &matrix); friend Matrix<T>* operator*(const Matrix<T> &m1, const Matrix<T> &m2); }; } #endif |
矩阵式CPP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | #include"Matrix.h" using namespace matrixClass; template<class T> Matrix<T>::Matrix(int d) : dimension{d}, m{new T *[d]} { //m = new T*[d]; for (int i = 0; i < d; i++) { m[i] = new T[d]; } } // COPY-CONSTRUCTOR template<class T> Matrix<T>::Matrix(const Matrix &original) : dimension{original.dimension}, m{new T *[original.dimension]} { for (int i = 0; i < dimension; i++) { *(m + i) = *(original.m + i); } } // DESTRUCTOR template<class T> Matrix<T>::~Matrix() { for (int i = 0; i < dimension; i++) { delete[] m[i]; } delete[] m; } template<class T> void Matrix<T>::set(int x, int y, T value) { m[x][y] = value; } template<class T> T Matrix<T>::get(int x, int y) const { return m[x][y]; } template<class T> int Matrix<T>::getDimension() const { return dimension; } template<class T> std::ostream& operator<<(std::ostream& output, const Matrix<T>& matrix) { int dimension = matrix.getDimension(); for(int x = 0; x < dimension; x++) { for(int y = 0; y < dimension; y++) { output << matrix.get(x, y) <<""; } return output; } } template<class T> Matrix<T>* operator*(const Matrix<T>& m1, const Matrix<T>& m2) { int dimension = m1.getDimension(); Matrix<T>* m = new Matrix<T>(dimension); for(int x = 0; x < dimension; x++) { for(int y = 0; y < dimension; y++) { T value = 0; for(int i = 0; i < dimension; i++) { value += m1.get(x, i) * m2.get(i, y); } m->set(x, y, value); } } return m; } |
主CPP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #include <iostream> #include"Matrix.h" using namespace matrixClass; using namespace std; int main() { Matrix<int> m(2); m.set(0, 0, 1); m.set(0, 1, 2); m.set(1, 0, 3); m.set(1, 1, 4); cout << m <<"*" << endl << m <<"=" << endl; return 0; } |
在
你可以使用它内置的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | template<class T> class Matrix { ... ... friend std::ostream& operator<<(std::ostream& output, const Matrix<T>& matrix) { int dimension = matrix.getDimension(); for(int x = 0; x < dimension; x++) { for(int y = 0; y < dimension; y++) { output << matrix.get(x, y) <<""; } return output; } } ... ... }; |
或使
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | // class declaration template<class T> class Matrix; // function declaration template<class T> std::ostream& operator<<(std::ostream& output, const Matrix<T>& matrix); // class definition template<class T> class Matrix { ... ... friend std::ostream& operator<< <T>(std::ostream& output, const Matrix<T>& matrix); ... ... }; // function definition template<class T> std::ostream& operator<<(std::ostream& output, const Matrix<T>& matrix) { int dimension = matrix.getDimension(); for(int x = 0; x < dimension; x++) { for(int y = 0; y < dimension; y++) { output << matrix.get(x, y) <<""; } return output; } } |
关于未定义的错误和参考模板,实现CAN的湖泊为什么只在头文件?
这个问题的答案与你的地址和
我想它这样的。这两个非成员函数的算子是这意味着他们是独立
1 2 3 4 5 | template<class T> std::ostream& operator<<(std::ostream& output, const Matrix<T>& matrix); template<class T> Matrix<T>* operator*(const Matrix<T>& m1, const Matrix<T>& m2); |
现在,因为有
1 2 3 4 5 | template<class U> std::ostream& operator<<(std::ostream& output, const Matrix<U>& matrix); template<class U> Matrix<U>* operator*(const Matrix<U>& m1, const Matrix<U>& m2); |
现在,你可以让他们
1 2 3 4 5 6 7 8 9 10 | template<class T> class Matrix { ... template<class U> friend std::ostream &operator<<(std::ostream&, const Matrix<U> &matrix); template<class U> friend Matrix<U>* operator*(const Matrix<U> &m1, const Matrix<U> &m2); }; |
最后,他们都需要在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | namespace matrixClass { // BEGIN Forward declarations template<class T> class Matrix; template<class U> std::ostream &operator<<(std::ostream&, const Matrix<U> &matrix); template<class U> Matrix<U>* operator*(const Matrix<U> &m1, const Matrix<U> &m2); // END Forward declarations template<class T> class Matrix { ... template<class U> friend std::ostream &operator<<(std::ostream&, const Matrix<U> &matrix); template<class U> friend Matrix<U>* operator*(const Matrix<U> &m1, const Matrix<U> &m2); }; ... template<class U> std::ostream& operator<<(std::ostream& output, const Matrix<U>& matrix) { ... // your implementation goes here } template<class U> Matrix<U>* operator*(const Matrix<U>& m1, const Matrix<U>& m2) { ... // your implementation goes here } } // end of namespace matrixClass |
所有这些模板代码应该在头文件,它matrix.h,安切洛蒂已经被提到。
所以,我认为你应该改变