【问题标题】:C++ template operator+ how to make diffrent instances work with itC ++模板运算符如何使不同的实例使用它
【发布时间】:2013-03-29 21:02:58
【问题描述】:

首先我有 Matrix 模板 Matrix 和这个模板 Matrix 的特化。但是特化是用构造函数创建的,其中参数是矩阵的大小。所以在示例代码中 A 和 Z 具有相同的维度。所以我想让 add 运算符使用它。但是编译器说:错误:'Z + A'中的'operator +'不匹配。那么我需要如何为 Matrix 编写 operator+ 才能与 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;
    }
};

当我尝试添加例如 Matrix 和 Matrix 这会产生错误。我必须如何在两个模板中定义它们将一起工作的 operator+?我可以在专业化模板中重载 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 
}

【问题讨论】:

  • 为什么要能够添加不兼容的矩阵?

标签: c++ templates operators operator-overloading


【解决方案1】:

我真的不知道你为什么要将不同维度的矩阵相加,但为了做到这一点,你必须将方法转换为矩阵参数维度上的方法模板:

#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&lt;T,0&gt; 是处理动态维度的特化,因此您必须为其特化运算符:

// 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&lt;T,0&gt;:

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 &amp; 参数的代码(或者干脆去掉在这种情况下似乎不是很有用的非 const 参数版本)。

注意使用static assert 来限制在非交换版本的运算符中使用具有相等或更大维数的矩阵的运算符(这是 C++11 特性)。

有关更多详细信息,请参阅 this question 关于 min 不是 constexpr 函数模板的主题。

【讨论】:

  • 它们的尺寸相同。基本模板在模板中具有大小,但在模板中空间化为零,但构造函数具有我们设置矩阵大小的参数。所以它们的尺寸相同,但制作方式不同。
  • 只是化妆品:我认为您在最后一个 sn-p 的第 12 行中有虚假逗号
  • 谢谢,一切顺利。我知道我的第一篇文章不清楚,问题也没有很好地解释。对不起那个错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-15
  • 2023-03-03
  • 1970-01-01
  • 2021-04-08
  • 2017-05-03
  • 1970-01-01
  • 2012-04-26
相关资源
最近更新 更多