SungwonAhn
SungwonAhn

Reputation: 57

matrix transpose template

When I try to write a code for matrix transpose using template I have this following error.

Error 1 error C2248: 'Matrix::elements' : cannot access private member declared in class 'Matrix'

Can anyone give me how to fix this error?

//Matrix.h
#include <iostream>
#include <vector>
using namespace std;

template<class T, int m, int n>
class Matrix;


template<class T, int m, int n>
class Matrix
{
vector<vector<T>> elements;
int nrow;
int ncol;

public:
Matrix();
~Matrix();
void print();

Matrix<T, n, m> transpose();

};

template<class T, int m, int n>
Matrix<T, m, n>::Matrix() : nrow(m), ncol(n)
{
for (int i = 0; i < nrow; i++){
    vector<T> row(ncol, i);
    elements.push_back(row);
}
}

template<class T, int m, int n>
Matrix<T, m, n>::~Matrix(){}

template<class T, int m, int n>
Matrix<T, n, m> Matrix<T, m, n>::transpose(){
Matrix<T, n, m> m;
for (int i = 0; i < nrow; ++i){
    for (int j = 0; j < ncol; ++j){
        m.elements[j][i] = elements[i][j];
    }
}
return m;
}

template<class T, int m, int n>
void Matrix<T, m, n>::print()
{
for (int i = 0; i < nrow; i++){
    for (int j = 0; j < ncol; j++)
    {
        cout << elements[i][j] << " ";
    }
    cout << endl;
}
}

//main.cpp

#include "Matrix.h"
using namespace std;

int main()
{
Matrix<int, 3, 2> a;
Matrix<int, 3, 2> b;
Matrix<int, 2, 3> c;
c = a.transpose();
c.print();
}

Upvotes: 2

Views: 1049

Answers (3)

sugy
sugy

Reputation: 61

The error is with the following function in your code:

template<class T, int m, int n>
Matrix<T, n, m> Matrix<T, m, n>::transpose() {
    Matrix<T, n, m> m;
    for (int i = 0; i < nrow; ++i) {
        for (int j = 0; j < ncol; ++j) {
            m.elements[j][i] = elements[i][j];
        }
    }
    return m;
}

The reason for the error is that you are creating a new Matrix m. In this Matrix elements is a private variable and hence you can not access it. I would suggest either creating a public getter function to return a pointer to elements or making elements a public variable (but that may not be good style as it doesn't encapsulate the data).

Your getter function can be a simple:

vector<vector<T> >* get_elements_ptr() {
    return &elements;
}

Your problematic function should then look something like:

template<class T, int m, int n>
Matrix<T, n, m> Matrix<T, m, n>::transpose() {
    Matrix<T, n, m> m;
    for (int i = 0; i < nrow; ++i) {
        for (int j = 0; j < ncol; ++j) {
            m.get_elements_ptr()->at(j)[i] = elements[i][j];
        }
    }
    return m;
}

This will fix your issue. However, on a side note I think your project design can be tweaked a bit altogether to totally avoid having a Matrix inside another Matrix object. Have you considered having a pointer to a dynamically allocated Matrix instead? This will reduce the amount of copying your program does tremendously and will improve both the memory and run-time efficiency of your program greatly.

Hope this helps!

Upvotes: 0

songyuanyao
songyuanyao

Reputation: 172934

Matrix<T, n, m> and Matrix<T, m, n> are different classes at all when m != n. It means you couldn't access the private member of Matrix<T, n, m> in the member function of Matrix<T, m, n>.

You might add friend declaration to solve the issue:

template<class T, int m, int n>
class Matrix
{

    vector<vector<T>> elements;
    int nrow;
    int ncol;

    public:
    Matrix();
    ~Matrix();
    void print();

    Matrix<T, n, m> transpose();

    friend class Matrix<T, n, m>;
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
};

Upvotes: 1

R Sahu
R Sahu

Reputation: 206607

The problem is that Matrix<T, m, n> and Matrix<T, n, m> are different classes when m and n are not the same. One cannot access the private members of the other. You can avoid the access problems by providing public member functions that provide access to the private member variables.

You won't notice the problem if m and n are the same.

Upvotes: 1

Related Questions