c++模板操作符+如何使不同的实例与它一起工作
C++ template operator+ how to make diffrent instances work with it
首先我有矩阵模板Matrix
下面的矩阵模板代码:
template<typename T,int Roz>
class Matrix
{
public:
T tab[Roz][Roz];
int z=Roz;
Matrix()
{
for(int i=0;i<Roz;++i)
for(int j=0;j<Roz;++j)
tab[i][j]=0;
}
T& operator()(int x,int y){
return tab[x-1][y-1];
}
//Problematic operator
Matrix& operator+(Matrix<T,Roz> b)
{
Matrix<T,Roz> tmp;
for(int i=0;i<Roz;++i)
for(int j=0;j<Roz;++j)
tmp.tab[i][j]=this->tab[i][j]+b.tab[i][j];
}
friend ostream& operator<<(ostream& out, Matrix<T,Roz> &v)
{
for(int i=0;i<v.z;++i)
{
for(int j=0;j<v.z;++j)
out<<v.tab[i][j]<<" ";
out<<endl;
}
return out;
}
};
//Specialization template
template<class T>
class Matrix<T,0>
{
private:
Matrix()
{
}
public:
vector<vector<T> > tab;
int z=0;
Matrix(int z)
{
for(int i=0;i<z;++i)
tab.push_back(vector<T>(z));
this->z = z;
for(int i=0;i<z;++i)
for(int j=0;j<z;++j)
tab[i][j]=0;
}
T& operator()(int x,int y){
return tab[x-1][y-1];
}
//Problematic operator
Matrix& operator+(Matrix<T,0> b)
{
Matrix<T,0> tmp(b.z);
for(int i=0;i<z;++i)
for(int j=0;j<z;++j)
tmp.tab[i][j]=this->tab[i][j]+b.tab[i][j];
}
//Problematic operator
Matrix& operator+(Matrix<T,0> &b)
{
Matrix<T,0> tmp(b.z);
for(int i=0;i<z;++i)
for(int j=0;j<z;++j)
tmp.tab[i][j]=this->tab[i][j]+b.tab[i][j];
}
friend ostream& operator<<(ostream& out, Matrix<T,0> &v)
{
for(int i=0;i<v.z;++i)
{
for(int j=0;j<v.z;++j)
out<<v.tab[i][j]<<" ";
out<<endl;
}
return out;
}
};
当我尝试添加例如矩阵<int,3> and Matrix <Int,> this会出错。我必须如何在两个模板中定义运算符+,它们将一起工作?我可以在专门化模板中重载operator+吗?
当我尝试添加A + z时,下面的代码出错
int main()
{
Matrix<int,3> A, B;
Matrix<int, 4> C;
Matrix<int, 0> Z(3);
A(1,1)=1;
B(1,1)=2;
Z(1,1)=1;
Z + A;//<------- here error between diffrent instance of Matrix template
}
我真的不知道为什么要将不同维度的矩阵相加,但是为了做到这一点,您必须将方法转换为矩阵参数维度的方法模板:
#include <type_traits>
template <int Roz2>
Matrix& operator+(Matrix<T,Roz2> b)
{
// check matrix argument size compatibility
std::static_assert(Roz2 >= Roz, "incompatible matrices for operator+()");
Matrix<T,Roz> tmp;
for(int i=0;i<Roz;++i)
for(int j=0;j<Roz;++j)
tmp.tab[i][j]=this->tab[i][j]+b.tab[i][j];
}
由于Matrix<T,0>
是处理动态维度的专门化,因此必须专门化它的运算符:
// in the generic template
Matrix& operator+(Matrix<T,0> b)
{
assert (b.z < Roz, "incompatible dynamic matrix for operator+");
Matrix<T,0> tmp(b.Roz);;
for(int i=0;i<Roz;++i)
for(int j=0;j<Roz;++j)
tmp.tab[i][j]=this->tab[i][j]+b.tab[i][j];
}
和在Matrix<T,0>
中:
template <int Roz>
Matrix& operator+(Matrix<T,Roz> b)
{
assert(Roz >= z,"....");
Matrix<T,0> tmp(b.z);
for(int i=0;i<z;++i)
for(int j=0;j<z;++j)
tmp.tab[i][j]=this->tab[i][j]+b.tab[i][j];
}
然而,在上面的解中,算子是不可交换的。为了做到这一点,我们需要做一些改变:
// define a min operator as constexpr in case the existing one is not
template<typename T> constexpr
T const& rmin(T const& a, T const& b) {
return a > b ? b : a;
}
// generic operator
template <int Roz2>
Matrix<T,rmin(Roz,Roz2)>& operator+(Matrix<T,Roz2> b)
{
constexpr int R = min(Roz,Roz2);
Matrix<T,R> tmp;
for(int i=0;i<R;;++i)
for(int j=0;j<R;++j)
tmp.tab[i][j]=this->tab[i][j]+b.tab[i][j];
}
// specialized operator on Roz=0 argument
Matrix<T,0>& operator+(Matrix<T,0> b)
{
const int r = min(z,b.z);
Matrix<T,0> tmp(r);
for(int i=0;i<r;;++i)
for(int j=0;j<r;++j)
tmp.tab[i][j]=this->tab[i][j]+b.tab[i][j];
}
// specialized operator in Roz=0 template
Matrix& operator+(Matrix<T,Roz> b)
{
return b + *this;
}
您将不得不复制const &
参数的操作符代码(或者可能只是摆脱非const参数版本,在这种情况下似乎不是很有用)。
注意,在运算符的非交换版本中,使用静态断言来限制对等于或大于等于维数的矩阵使用运算符(这是c++ 11的一个特性)。
请参阅有关min
不是constexpr
函数模板的主题的问题以了解更多详细信息。
相关文章:
- 这个C++编译器优化(在自身的实例上调用对象自己的构造函数)的名称是什么,它是如何工作的?
- 如何使实例化在我的 OpenGL 程序中工作?
- 以下代码如何工作以每次为唯一调用堆栈唯一实例化模板函数?
- 显式实例化无法正常工作
- 从Excel VBA调用C++DLL只能从Visual Studio中的调试实例工作
- CPU寄存器中返回的用户定义类型的C 对象.实例方法如何工作
- 模板类实例化如何与类继承协同工作
- 无限递归模板实例化使用clang时GCC工作正常
- boost :: Spirit :: Qi-与语法结构中的实例成员一起工作
- 如何使链表与类的多个实例一起工作
- GCC 4.9 中的模板实例化错误,在 GCC 4.8 中工作正常
- C++ 类模板显式实例化在 macOS 上工作,在 ubuntu 上不起作用
- 数组中的Memcpy只能正常工作1/20个实例
- OpenGL ES 3实例渲染失败,但在桌面上工作
- 用OSG Cookbook中的draw实例渲染点云数据不工作
- 不是在结构体内部工作,而是在结构体外部工作的自定义类实例
- 在工作精灵系统中添加实例的问题
- 对象的第二个实例不能正常工作
- 我的类的静态实例函数不像我预期的那样工作
- 我可以有超过1个sf::Clock实例吗?(sf::Clock是怎么工作的?)