mercredi 31 janvier 2018

An error about no match for friend template function

There's a matrix template class, and when I call the friend function "dot()", it crash and tell me "no match for call to this function. I wondered why and how to deal with it. And my code as follows with a little simplify,

#ifndef _ZMAT_H_
#define _ZMAT_H_
#include<iostream>

template <typename Type>
class Matrix {
    private:
        int Rows;
        int Cols;
        Type *Values; 
    public:
        Matrix(const int & row, const int & col);
        Matrix(const Matrix<Type> & mat);
        ~Matrix();

        template <typename FriendType, typename FriendOtherType, typename ReturnType>
        friend Matrix<ReturnType> & dot(const Matrix<FriendType> & mat, const Matrix<FriendOtherType> & other_mat);

        Type & operator() (const int & row, const int & col);
};

template <typename Type>
Type & Matrix<Type>::operator() (const int & row, const int & col) {
    return this->Values[row * this->Cols + col];
}

template <typename Type>
Matrix<Type>::Matrix(const Matrix<Type> & mat) {
    this->Rows = mat.Rows;
    this->Cols = mat.Cols;
    this->Values = new Type[this->Rows * this->Cols];
    for (int i = 0; i < this->Rows * this->Cols; ++i)
        this->Values[i] = mat.Values[i];
}

template <typename Type>
Matrix<Type>::Matrix(const int & row, const int & col) {
    this->Rows = row;
    this->Cols = col;
    this->Values = new Type[row * col];
}

template <typename Type>
Matrix<Type>::~Matrix() {
    delete [] this->Values;
}

template <typename FriendType, typename FriendOtherType, typename ReturnType=decltype(std::declval<FriendType>() * std::declval<FriendOtherType>())>
Matrix<ReturnType> & dot(const Matrix<FriendType> & mat, const Matrix<FriendOtherType> & other_mat) {
    if (mat.Cols != other_mat.Rows) {
        std::cerr << "Shape match failed." << std::endl;
        exit(0);
    }
    Matrix<ReturnType> * result = new Matrix<ReturnType>(mat.Rows, other_mat.Cols);
    for (int i = 0; i < mat.Rows; ++i)
        for (int j = 0; j < other_mat.Cols; ++j) {
            ReturnType temp = 0;
            for (int k = 0; k < mat.Cols; ++k) 
                temp += mat(i, k) * other_mat(k, j);
            (*result)(i, j) = temp;
        }
    return *result;
}
#endif

My main function as follows,

#include <iostream>
#include "Zmat.h"
int main() {
    Matrix<int> m6(2, 2, {0, 1,
                          1, 0});
    Matrix<int> m7(2, 2, {1, 2,
                          3, 4});
    Matrix<int> m8(dot(m6, m7));
    m8.display();
}

when the function "dot()" called, it crash and tell me "no match for call to ...".

Aucun commentaire:

Enregistrer un commentaire