Passing a 2D array to a function / constructor

Viewed 676

Can't convert float[3][3] to float **

I am writing a Program deal with Matrices as a practice for learning

But I am getting an error and am unable to assign float matrix[3][3] to float** I know that a 2D array is a Pointer of pointer, so a float **

My aim for this project is to write a Simple Matrix class to create matrices and do some basic matrix operations like addition and multiplication.

I am getting the following error:

In file included from main.cpp:2:0:
./matrix.h:12:5: note: candidate: Matrix::Matrix(int, int, float**)
     Matrix(int, int, float **elements);
     ^~~~~~
./matrix.h:12:5: note:   no known conversion for argument 3 from 
‘float [3][3]’ to ‘float**’

I know that changing the argument type from float[3][3] will solve it. But the size of the Matrix is not fixed, that's why I was opting for float**

This is the a part of my code:

main.cpp

#include"Matrix.h"

int main()
{
    float Identity[3][3] = 
    {
        {1.0, 0.0, 0.0},
        {0.0, 1.0, 0.0},
        {0.0, 0.0, 1.0}    
    };
    
    Matrix identity = Matrix(3, 3, Identity);
}

Matrix.h

class Matrix
{
private
    MatrixData _matrix = MatrixData();
    
    Matrix(int rows, int columns, float **elements)
    {
        _matrix.rows = rows;
        _matrix.columns = columns;
        
        _matrix.elements = new float[rows * columns];
        
        for(int i = 0; i < rows; i++)
            for(int j = 0; j < columns; j++)
                _matrix.elements[(i * columns) + j] = elements[i][j];

    }    
}

MatrixData.h

struct MatrixData
{
    unsigned char rows;
    unsigned char columns;
    float *elements;
};

In the MatrixData class, elements are stored as a contiguous array.

To create a new Matrix a 2D array has to be passed int he class constructor.

If the constructor arg type is float * And I pass Identity[0] in the constructor, it works.

What I want is, to pass Identity and not something like Identity[0] or &Identity[0][0].

Can Anyone tell me what could the solution.

Thank You.

1 Answers

2D arrays are stored contigously, so you should probably do something like this example:

#include <iostream>

template<size_t N1, size_t N2>
void output(const float (&elements)[N1][N2])
{
    for (size_t i = 0; i < N1; i++)
    {
        for (size_t j = 0; j < N2; j++)
            std::cout << elements[i][j] << ' ';
        std::cout << std::endl;
    }
}
int main()
{

    float elements[3][3] = {
    {1,2,3},
    {1,2,3},
    {1,2,3}
    };
    output<3, 3>(elements);
}

Note how I've used templates because the array size is static, which is another mistake you did

Edit: I understand what you're trying to do, here's how:

Make the Matrix class a template class taking the template parameters rows and columns, and change the elements parameter into float elements[rows][columns]

template<size_t rows, size_t columns>
class Matrix
{
private:
    MatrixData _matrix = MatrixData();
public:
    Matrix(float elements[rows][columns])
    {
        _matrix.rows = rows;
        _matrix.columns = columns;

        _matrix.elements = new float[rows * columns];

        for (int i = 0; i < rows; i++)
            for (int j = 0; j < columns; j++)
                _matrix.elements[(i * columns) + j] = elements[i][j];

    }
};

Then you have to remove the rows and columns constructor parameters because you already have them as template parameters.

Now the object declaration should look like this:

int main()
{
    float Identity[3][3] =
    {
        {1.0, 0.0, 0.0},
        {0.0, 1.0, 0.0},
        {0.0, 0.0, 1.0}
    };

    Matrix<3, 3> identity(Identity);
}
Related