2

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.

3
  • 2D array is stored contiguously, why should it be convertible into float**? What does the second pointer stand for? Consider float* instead. Commented Aug 8, 2020 at 16:36
  • The elements in the Matrix class are stored in a contiguous array, but the elements are passed in as a 2D array to make it readable. _matrix.elements is a float* Commented Aug 8, 2020 at 16:39
  • I tried passing Identity[0] to the constructor and changed the arg type to float *. It worked! Thanks Evg. Commented Aug 8, 2020 at 16:53

1 Answer 1

2

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);
}
Sign up to request clarification or add additional context in comments.

9 Comments

elements needs to be a reference. Are you sure this compiles?
@cigien Yes it compiles perfectly fine on GDB and Visual C++
Aah, I see, you're calling it with output<3,3>(elements);. But this makes the parameter of output be a dynamic array, not a reference to a static array. Which is fine, I suppose.
@BilyDev Thanks a lot for your help, I am accepting your answer.
You are making a copy of the array in the output function. It could have been output(const float (&elements)[N1][N2])
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.