0

まず、Matrix テンプレート Matrix< typename T, int Roz> と、このテンプレート Matrix の特殊化があります。ただし、特殊化は、引数が行列のサイズであるコンストラクターを使用して作成されます。したがって、コード例では、A と Z の次元は同じです。だから私は追加演算子をそれで動作させたいと思っています。しかし、コンパイラは次のように言います: エラー: 'Z + A' の 'operator+' に一致しません。では、Matrix で動作する 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 < int,3 > と Matrix < int, 0 > を追加しようとすると、エラーが発生します。一緒に機能する両方のテンプレートで 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 
}
4

1 に答える 1

0

異なる次元の行列を合計したい理由はよくわかりませんが、それを行うには、メソッドを行列引数の次元のメソッド テンプレートに変換する必要があります。

#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 の機能です) での演算子の使用を制限していることに注意してください。

詳細については、関数テンプレートではないというトピックに関するこの質問を参照してください。minconstexpr

于 2013-04-07T21:32:26.060 に答える