Nested std::initializer list problem

I wrote this code here:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Matrix::Matrix(std::initializer_list<std::initializer_list<int>> matrix)
{
	std::vector<std::vector<int>> mat = matrix;
	Rows = matrix.size();
	std::cout << Rows<< " ";
	Index = Rows * Cols;
	cell.resize(Rows);
	for (int i = 0; i < Rows; i++) {
		Cols = matrix.size();
		cell[i].resize(Cols);
		for (int j = 0; j < Cols; j++) {
			if (j != Cols) {
				cell[i][j] = mat[i][j];
			}
		}
	}
}


I can't convert the whole nested list into nested vector, and i want to calculate this matrix:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

	try {
                Matrix m1{{1, 2, 3}, //
				  {4, 5, 6},{7,8,9}}
		Matrix m2{{1, 2, 3}, //
				  {4, 5, 6}};
		Matrix m3(m2);
		m2(1, 1) = 5;
	std::cout << "m1:" << m1 << std::endl;
	std::cout << "m3:" << m3 << std::endl;

	}
	catch (std::exception &e) {
		std::cout << "Exception: " << e.what() << "!" << std::endl;
	}
	catch (...) {
		std::cout << "Unknown exception caught!" << std::endl;
	}


this is my header file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Matrix
{
	friend std::ostream &operator<<(std::ostream &out, const Matrix &vec);
private:
	int Rows;
	int Cols;
	int Index = Rows * Cols;
	std::vector<std::vector<float>> cell;
public:
	Matrix();
	Matrix(int rows, int cols, float num);
	Matrix(std::initializer_list<std::initializer_list<int>> matrix);
	int getelement(int i,int j);
	int getnumrows();
	int getnumcols();
	friend Matrix operator*(const Matrix &matrix1, const Matrix &matrix2);
	float& operator()(int rows, int cols);
	~Matrix();
};


The problem with my code is the error with this code std::vector<std::vector<int>> mat = matrix;

I can use Rows = matrix.size(); and it will return the outer elements but not the inner ones.

how can I extract elements from the inner brackets?
Last edited on
Line 9 would be

Cols = matrix[i].size(); // Note: [i]
that won't work
This is my entire c++ file for constructor:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include "Matrix.h"
#include <iostream>
#include <vector>
#include <array>
#include <iomanip>
#include <initializer_list>

Matrix::Matrix()
{}

Matrix::Matrix(int rows, int cols, float num)
{
	Index = rows * cols;
	Rows = rows;
	Cols = cols;
	cell.resize(rows);
	for (int i = 0; i < rows; i++) {
		cell[i].resize(cols);
		for (int j = 0; j < cols; j++) {
			cell[i][j] += num;
		}
	}
}
Matrix::Matrix(std::initializer_list<std::initializer_list<int>> matrix)
{
	std::vector<std::vector<int>> mat = matrix;
	Rows = matrix.size();
	std::array<int, 2> vine;
	std::cout << Rows<< " ";
	Index = Rows * Cols;
	cell.resize(Rows);
	for (int i = 0; i < Rows; i++) {
		Cols = matrix[i].size();
		cell[i].resize(Cols);
		for (int j = 0; j < Cols; j++) {
			if (j != Cols) {
				cell[i][j] = mat[i][j];
			}
		}
	}
}

int Matrix::getelement(int i, int j)
{
	return this->cell[i][j];
}

int Matrix::getnumrows()
{
	return this->Rows;
}

int Matrix::getnumcols()
{
	return this->Cols;
}


float & Matrix::operator()(int rows, int cols)
{
	return cell[rows][cols];
}



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <iostream>
#include <vector>
#include <algorithm>
#include <iomanip>

class Matrix
{
    public:
        Matrix() = default ;

        Matrix( std::size_t nrows, std::size_t ncols, double num = 0 )
            : mtx( nrows, std::vector<double>( ncols, num ) ) {}
        
        // note: type corrected to double 
        Matrix( std::initializer_list<std::initializer_list<double> > ilist ) : mtx( ilist.size() )
        {
            std::size_t col_size = 0 ; // size of the largest col
            for( const auto& row : ilist ) col_size = std::max( col_size, row.size() ) ;

            for( auto& row : mtx ) row.resize(col_size) ; // resize all columns to col_size

            std::size_t row_num = 0 ;
            for( const auto& row : ilist ) // copy what is there in each row of ilist
                std::copy( row.begin(), row.end(), mtx[row_num++].begin() ) ;
        }

        // checked element access
        double& element_at( std::size_t i, std::size_t j ) { return mtx.at(i).at(j) ; }
        double element_at( std::size_t i, std::size_t j ) const { return mtx.at(i).at(j) ; }

        // unchecked element access
        double& operator() ( std::size_t i, std::size_t j ) { return mtx[i][j] ; }
        double operator() ( std::size_t i, std::size_t j ) const { return mtx[i][j] ; }

        std::size_t num_rows() const { return mtx.size() ; }
        std::size_t num_colss() const { return mtx.empty() ? 0 : mtx.front().size() ; }

    private: std::vector<std::vector<double> > mtx;

	friend std::ostream &operator<<( std::ostream& out, const Matrix& matrix )
	{
	    for( const auto& row : matrix.mtx )
            {
                for( double v : row ) out << std::setw(10) << v ;
                out << '\n' ;
            }
        return out ;
	}
};

int main()
{
    // 4 rows x 7 cols
    const Matrix mtx { { 10, 11, 12 }, { 20, 21 }, { 30, 31, 32, 33, 34, 35, 36 }, {}, {40} } ;
    std::cout << std::fixed << std::setprecision(1) << mtx << '\n' ;
}

http://coliru.stacked-crooked.com/a/4b8a7adf1ba2ad4a
Last edited on
If you are using the matrix for a 2D map instead of being a row of vectors (but there are applications for vector of vectors of course), I suggest you to considering how easy it is to treat a single vector as a 2D array using (w*y + x) for indexing, you will need to store the width and height in a variable instead of the vector size. This is how the layout of a 2D fixed sized array looks like.

edit: well I didn't notice this is a math class, a better solution is to just say "Matrix3x3" and just create a bunch of variables or a fixed sized array inside of it. But overall this post is just a nitpick.
Last edited on
is there anything more simple?
more simple than a 1-d vector? What are you looking for?
std::initializer_list<std::initializer_list<double>>

simplified usage of the nested initializer list.
Is there other methods?
Topic archived. No new replies allowed.