C++中的朋友和模板 [英] friend and template in C++
问题描述
我的 C++ 代码示例中有一个大问题.朋友"和模板"有问题.
错误消息:
Matrix.h:26:79:警告:
友元声明'std::ostream&matrixClass::operator<<(std::ostream&, const matrixClass::Matrix&)'声明一个非模板函数 [-Wnon-template-friend]朋友 std::ostream &operator<<(std::ostream&, const Matrix &matrix);
Matrix.h:26:79:注意:
<块引用>(如果这不是您想要的,请确保函数模板
已经声明并在此处的函数名后添加<>)
Matrix.h:28:77:警告:
<块引用> 友元声明 'matrixClass::Matrix*
matrixClass::operator*(const matrixClass::Matrix&, constmatrixClass::Matrix&)' 声明了一个非模板函数[-Wnon-template-friend]朋友矩阵*操作符*(const Matrix &m1, const Matrix &m2);
Matrix.cpp:1:0:
<块引用>C:\Users\Peter\CLionProjects\PK\untitled76\Matrix.h:26:79:警告:朋友声明 'std::ostream&matrixClass::operator<<(std::ostream&, const matrixClass::Matrix&)'声明一个非模板函数 [-Wnon-template-friend]朋友 std::ostream &operator<<(std::ostream&, const Matrix &matrix);
Matrix.h:26:79:注意:
<块引用>(如果这不是您想要的,请确保函数模板
已经声明并在此处的函数名后添加<>)
Matrix.h:28:77:警告:
<块引用> 友元声明 'matrixClass::Matrix*
matrixClass::operator*(const matrixClass::Matrix&, constmatrixClass::Matrix&)' 声明了一个非模板函数[-Wnon-template-friend]朋友矩阵*操作符*(const Matrix &m1, const Matrix &m2);
CMakeFiles\untitled76.dir/objects.a(main.cpp.obj):在函数`main'中:
main.cpp:8:未定义的引用main.cpp:8:对 matrixClass::Matrix
matrixClass::Matrix::set(int, int, int)'
的未定义引用main.cpp:10: 未定义引用
main.cpp:11:对 matrixClass::Matrix
matrixClass::Matrix::set(int, int, int)'
的未定义引用main.cpp:12: 未定义引用
main.cpp:13:对 matrixClass::Matrix
matrixClass::operator<<(std::ostream&, matrixClass::Matrix const&)'
的未定义引用main.cpp:15: 未定义引用
main.cpp:15: 对 matrixClass::operator<<(std::ostream&, matrixClass::Matrix
matrixClass::Matrix::~Matrix()'
的未定义引用main.cpp:8:对
的未定义引用main.cpp:8:对`matrixClass::Matrix::~Matrix()'的未定义引用
代码:Matrix.h
#ifndef MATRIX_H_#define MATRIX_H_#include 命名空间矩阵类{模板类矩阵{私人的:整数维度;Tm值;民众:矩阵(int d);矩阵(const Matrix & original);~矩阵();void set(int x, int y, T 值);T get(int x, int y) const;int getDimension() const;朋友 std::ostream &operator<<(std::ostream&, const Matrix<T> &matrix);朋友矩阵<T>*运算符*(const Matrix<T> &m1, const Matrix<T> &m2);};}#万一
Matrix.cpp
#include "Matrix.h"使用命名空间矩阵类;模板矩阵::Matrix(int d): 尺寸{d}, m{new T *[d]} {//m = 新 T*[d];for (int i = 0; i < d; i++) {m[i] = 新 T[d];}}//复制构造函数模板矩阵<T>::Matrix(const Matrix &original):尺寸{原始尺寸},m{new T *[original.dimension]} {for (int i = 0; i <维数; i++) {*(m + i) = *(original.m + i);}}//析构函数模板矩阵::~矩阵(){for (int i = 0; i <维数; i++) {删除[] m[i];}删除[]米;}模板void Matrix::set(int x, int y, T 值) {m[x][y] = 值;}模板T 矩阵::get(int x, int y) const {返回 m[x][y];}模板int Matrix::getDimension() const {返回维度;}模板std::ostream&运算符<<(std::ostream&输出,const矩阵&矩阵){int 维度 = matrix.getDimension();for(int x = 0; x <维度; x++) {for(int y = 0; y <维度; y++) {输出<矩阵<T>*运算符*(const Matrix<T>& m1, const Matrix<T>& m2){int 维度 = m1.getDimension();矩阵*m=新矩阵(维度);for(int x = 0; x <维度; x++) {for(int y = 0; y <维度; y++) {T值=0;for(int i = 0; i <维数; i++) {值 += m1.get(x, i) * m2.get(i, y);}m->set(x, y, value);}}返回 m;}
main.cpp
#include #include "Matrix.h"使用命名空间矩阵类;使用命名空间标准;int main() {矩阵米(2);m.set(0, 0, 1);m.set(0, 1, 2);m.set(1, 0, 3);m.set(1, 1, 4);cout<<米<<*"<<结束<<米<<="<<结束;返回0;}
在 friend
声明中 operator<<
指的是一个非模板函数,而它的定义说它是一个模板函数;他们不匹配.
您可以使用 friend
声明内联定义它(作为非模板函数):
template类矩阵{……朋友 std::ostream&运算符<<(std::ostream&输出,const矩阵&矩阵){int 维度 = matrix.getDimension();for(int x = 0; x <维度; x++) {for(int y = 0; y <维度; y++) {输出<
或者使 friend
声明引用函数模板:
//类声明模板类矩阵;//函数声明模板std::ostream&运算符<<(std::ostream&输出,const矩阵&矩阵);//类定义模板类矩阵{……朋友 std::ostream&运算符<<<T>(std::ostream&输出,const矩阵<T>&矩阵);……};//函数定义模板std::ostream&运算符<<(std::ostream&输出,const矩阵&矩阵){int 维度 = matrix.getDimension();for(int x = 0; x <维度; x++) {for(int y = 0; y <维度; y++) {输出<
关于未定义的引用错误,参见为什么模板只能在头文件中实现?
I have a big problem in my C++ Code example. There is something wrong with 'friend' and the 'template'.
Error Messages:
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);
Matrix.h:26:79: note:
(if this is not what you intended, make sure the function template
has already been declared and add <> after the function name here)
Matrix.h:28:77: warning:
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);
Matrix.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);
Matrix.h:26:79: note:
(if this is not what you intended, make sure the function template
has already been declared and add <> after the function name here)
Matrix.h:28:77: warning:
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);
CMakeFiles\untitled76.dir/objects.a(main.cpp.obj): In function `main':
main.cpp:8: undefined reference to
main.cpp:8: undefined reference to matrixClass::Matrix<int>::Matrix(int)'<br>
main.cpp:10: undefined reference to
matrixClass::Matrix::set(int, int, int)'
main.cpp:11: undefined reference to matrixClass::Matrix<int>::set(int, int, int)'<br>
main.cpp:12: undefined reference to
matrixClass::Matrix::set(int, int, int)'
main.cpp:13: undefined reference to matrixClass::Matrix<int>::set(int, int, int)'<br>
main.cpp:15: undefined reference to
matrixClass::operator<<(std::ostream&, matrixClass::Matrix const&)'
main.cpp:15: undefined reference to matrixClass::operator<<(std::ostream&, matrixClass::Matrix<int> const&)'<br>
main.cpp:8: undefined reference to
matrixClass::Matrix::~Matrix()'
main.cpp:8: undefined reference to `matrixClass::Matrix::~Matrix()'
Code: Matrix.h
#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
Matrix.cpp
#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;
}
main.cpp
#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;
}
In friend
declaration operator<<
refers to a non-template function, while its definition says it's a template function; they don't match.
You can define it inline with the friend
declaration (as non-template function):
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;
}
}
... ...
};
Or make the friend
declaration referring to the function template:
// 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;
}
}
And about the undefined reference error, see Why can templates only be implemented in the header file?
这篇关于C++中的朋友和模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!