Is there any way to implement brace-enclosed initialization list?
main.cpp
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 66
|
#include <iostream>
#include <stdexcept>
#include "Matrix.h"
// Test Driver
int main()
{
Matrix<int> matrix1( 3 , 1 );
matrix1[0][0] = -4;
matrix1[1][0] = 1;
matrix1[2][0] = 5;
std::cout << "Matrix1:\n" << matrix1;
Matrix<int> matrix2( 3 , 3 );
matrix2[0][0] = 1;
matrix2[0][1] = 2;
matrix2[0][2] = 3;
matrix2[1][0] = 4;
matrix2[1][1] = 5;
matrix2[1][2] = 6;
matrix2[2][0] = 7;
matrix2[2][1] = 8;
matrix2[2][2] = 9;
std::cout << "\nMatrix2:\n" << matrix2;
std::cout << "\nmatrix1 * matrix2 = \n";
try {
std::cout << matrix1 * matrix2;
}
catch( std::invalid_argument invalidArg ) {
std::cerr << "Error: " << invalidArg.what();
}
Matrix<int> matrix3( 3 , 3 );
matrix3[0][0] = -4;
matrix3[0][1] = 2;
matrix3[0][2] = 4;
matrix3[1][0] = 1;
matrix3[1][1] = 0;
matrix3[1][2] = 6;
matrix3[2][0] = 5;
matrix3[2][1] = 8;
matrix3[2][2] = 5;
std::cout << "\nMatrix3:\n" << matrix3;
std::cout << "\nMatrix2 * Matrix3 = \n";
try {
std::cout << matrix2 * matrix3;
}
catch( std::invalid_argument invalidArg ) {
std::cerr << "Error: " << invalidArg.what();
}
/*
// Is there a way to use brace-enclosed initialization list like this?
Matrix<int> matrix4 = { {1 , 2 , 3 } ,
{4 , 5 , 6 } ,
{7 , 8 , 9 } };
std::cout << matrix4;
*/
return 0;
}
|
Matrix.h
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 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
#ifndef MATRIX_H_INCLUDED
#define MATRIX_H_INCLUDED
#include <vector>
#include <algorithm>
#include <stdexcept>
/*************************************************************************
Two-Dimensional Matrix
Current Public Operations
1. operator[]
2. row()
3. col()
4. setRow()
5. setCol()
6. operator* - Matrix Multiplication
Construction
1. No Arguments
2. int rows , int columns
*************************************************************************/
template <typename Object>
class Matrix
{
public:
// Default Constructor
Matrix();
Matrix( int rows , int cols );
// Read-Only operator[]
const std::vector<Object> & operator[] ( int row ) const;
// Read-Write operator[]
std::vector<Object> & operator[] ( int row );
// Matrix Multiplication
Matrix operator* ( const Matrix &rhs ) const;
int row() const;
int col() const;
void setRow( int row );
void setCol( int col );
private:
std::vector< std::vector<Object> > arr;
};
/*************************************************************************
Implementation
*************************************************************************/
template <typename Object>
Matrix<Object>::Matrix() {}
template <typename Object>
Matrix<Object>::Matrix( int rows , int cols ): arr( rows )
{
for( auto& thisRow : arr ) {
thisRow.resize( cols );
}
}
template <typename Object>
const std::vector<Object> & Matrix<Object>::operator[] ( int row ) const
{
return arr[row];
}
template <typename Object>
std::vector<Object> & Matrix<Object>::operator[] ( int row )
{
return arr[row];
}
template <typename Object>
int Matrix<Object>::row() const
{
return arr.size();
}
template <typename Object>
void Matrix<Object>::setRow( int row )
{
arr.resize( row );
}
template <typename Object>
void Matrix<Object>::setCol( int col )
{
for( auto &s : arr ) {
s.resize( col );
}
}
template <typename Object>
int Matrix<Object>::col() const
{
return row() ? arr[0].size() : 0;
}
template <typename Object>
Matrix<Object> Matrix<Object>::operator* ( const Matrix &rhs ) const
{
// Check for compatible dimensions
if( this->col() == rhs.row() ) {
Matrix result{ this->row() , rhs.col() };
// Initialize all cells to 0
for( int row = 0 ; row < result.row() ; row++ ) {
for( int col = 0 ; col < result.col() ; col++ ) {
result[row][col] = 0;
}
}
// Perform multiplication
for( int row = 0 ; row < result.row() ; row++ ) {
for( int col = 0 ; col < result.col() ; col++ ) {
for( int i = 0 ; i < this->col() ; i++ ) {
result[row][col] += this->arr[row][i] * rhs[i][col];
}
}
}
return result;
}
else {
throw std::invalid_argument
( "The given matrices do not have compatible dimensions for multiplication.\n" );
}
}
// Overload operator<< for Matrix Objects
template <typename Object>
std::ostream & operator<< ( std::ostream &out , Matrix<Object> matrix ) {
for( int row = 0 ; row < matrix.row() ; row++ ) {
out << "[ ";
for( int col = 0 ; col < matrix.col() ; col++ ) {
out << matrix[row][col] << " ";
}
out << ']' << std::endl;
}
return out;
}
#endif // MATRIX_H_INCLUDED
|
Last edited on
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
|
#include <iostream>
#include <vector>
#include <initializer_list>
template < typename T > struct matrix
{
matrix( std::initializer_list< std::initializer_list<T> > ilist ) : arr( ilist.begin(), ilist.end() )
{
std::size_t sz = 0 ;
for( const auto& row : arr ) if( sz < row.size() ) sz = row.size() ;
for( auto& row : arr ) row.resize(sz) ; // note: assumes that T is default constructible
// or throw if all rows are not of the same size
}
private: std::vector< std::vector<T> > arr ;
friend std::ostream& operator<< ( std::ostream& stm, const matrix<T>& m )
{
for( const auto& row : m.arr )
{
for( const T& v : row ) stm << v << ' ' ;
stm << '\n' ;
}
return stm ;
}
};
int main()
{
const matrix<int> m { { 1 , 2 , 3 } , { 4 , 5 , 6 } , { 7 , 8 , 9 } };
std::cout << m << '\n' ;
}
|
http://coliru.stacked-crooked.com/a/5cdc0eb043e740ea
@JLBorges
Beautiful :) it works.
Thank you so much. I've never encountered initializer_list before. It's good to know.
Topic archived. No new replies allowed.