Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I initialize with a 2 dimensional initializer_list?

I know, that vector class is initialized in the following way:

Vector::Vector(initializer_list<double> lst)
    :size{static_cast<int>(lst.size())},elem{new double[static_cast<int>(lst.size())]}
    {
        copy(lst.begin(),lst.end(),elem);
    }

Here is my Matrix class:

class Matrix{
private:
    int row;
    int col;
    double elem**
public:
    //Default Constructor:
    Matrix(int row,int col);
    //Initialized list constructor:
    Matrix(initializer_list<initializer_list<double>> lst);

I suppose, that I should use initialized lis in initialized list in order to create initialized matrix. How can I do it from the syntax point of view?

like image 276
Rob_Fir Avatar asked Jan 29 '23 20:01

Rob_Fir


2 Answers

It's the same principle that you used for Vector, but iterating throug a list of list:

Matrix(initializer_list<initializer_list<double>> lst) : 
                                   row{lst.size()}, 
                                   col{0}   // not sure if all cols are same size
{
    for (auto &x: lst)     // iterate through outer list to find largest inner list
        if (x.size()>col)
            col = x.size();
    cout<<row<<"x"<<col<<endl;   // educational purpose only -> remove
    elem=new double*[row];       
    auto it=lst.begin();         // iterate through outer list 
    for (int i=0; i<row; i++, it++) {
        elem[i]=new double[col];    
        std::copy(it->begin(),it->end(),elem[i]); // copy current inner list
    }
}

With this you can handle a 2D list like:

Matrix m{ {1,2,3},{4,5,6},{7,8,9}}; 

Online demo

Important remarks: It's always painful and error prone to manage memory manually. It would be easier to use std::vector instead of pointers to dynamically allocated arrays. For the matrix, you'd have the choice between a vector of vectors, or an flattened vector with some formula to find the element for a given row and column.

like image 104
Christophe Avatar answered Feb 06 '23 20:02

Christophe


I recommend to use std::array:

#include <array>

template<int ROWS, int COLUMS>
using Matrix = std::array<std::array<double, COLUMS>, ROWS>;

Matrix<3,3> m{ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 };

Or std::vector:

#include <vector>

using Matrix = std::vector<std::vector<double>>;

Matrix m{ {1.0, 2.0, 3.0}, {4.0, 5.0, 6.0}, {7.0, 8.0, 9.0} };

Or a class Matrix derived from std::vector:

#include <vector>

class Matrix
    : public std::vector<std::vector<double>>
{
public:
    Matrix( std::vector<std::vector<double>> && m )
        : std::vector<std::vector<double>>( m )
    {}
};

Matrix m( { {1.0, 2.0, 3.0}, {4.0, 5.0, 6.0}, {7.0, 8.0, 9.0} } );
like image 39
Rabbid76 Avatar answered Feb 06 '23 18:02

Rabbid76