Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initializing a matrix made of vectors inside constructor of class

I'm trying to build a game which has a matrix of chars. I'm trying to use a vector of vectors to build my matrix. My game.h has this:

#ifndef GAME_H
#define GAME_H
// includes
using namespace std;
class Game 
{
  private:
    int row;
    int col;
    vector<vector<char>>* matrix;
    // other atributtes

  public:
    Game();
    ~Game(){}
    // some functions
};
#endif

And in my game.cpp:

Game::Game()
{
    this->col = 20;
    this->row = 20;
    // Initialize the matrix
    this->matrix = new vector<vector<char>>(this->col);
    for(int i = 0 ; i < this->col ; i++)
       this->matrix[i].resize(this->row, vector<char>(row));
    // Set all positions to be white spaces
    for(int i = 0 ; i <  this->col; i++)
      for(int j = 0 ; j < this->row ; j++)
        this->matrix[i][j] = ' ';
}

It's giving me an error:

error: no match for ‘operator=’ (operand types are ‘__gnu_cxx::__alloc_traits<std::allocator<std::vector<char> > >::value_type {aka std::vector<char>}’ and ‘char’)
     this->matrix[i][j] = ' ';
                          ^~~

in the line:

this->matrix[i][j] = ' ';

I would like to know what's causing this and how can I set everything to be a whitespace in my constructor?

like image 627
Carlos A. Jimenez Holmquist Avatar asked May 15 '18 04:05

Carlos A. Jimenez Holmquist


2 Answers

Type of this->matrix is std::vector<std::vector<char>>*.

Type of this->matrix[i] is std::vector<std::vector<char>>

Type of this->matrix[i][j] is std::vector<char>.

Hence,

this->matrix[i][j] = ' ';

does not work.

Simplify your code. Change matrix to

std::vector<std::vector<char>> matrix; // Remove the pointer

Adjust your code accordingly.

like image 154
R Sahu Avatar answered Nov 14 '22 03:11

R Sahu


If I were you, I would have done it like this:

in games.hpp:

#ifndef GAME_H
#define GAME_H
// includes
template <class T>
class Game : public std::vector<std::vector<T>>
{
     private:
        int row;
        int col;

    public:
        Game();
       ~Game(){}
// some functions
};
#endif

in games.cpp

template<class T>
Game<T>::Game(int rr=20, int cc=20):
    row(rr), col(cc), std::vector<std::vector<T>>(rr, std::vector<T>(cc))
{
 //empty body   
}

This naturally will complicate the way you would have to access elements but it can be easily done by overloading the operator() that returns a reference to the position you want to access. Note by publicly inheriting the std::vector, we inherited all their operators and member functions and variables. Hence we also inherited the overloaded operator[] in std::vector class. Hence we can access any element by an overloaded operator as shown below:

template<class T>
T& Game<T>::operator()(int rr, int cc){
return this->operator[](rr)[cc];
}

In the return statement above, the first part calls the overloaded operator[] with an argument rr, which returns a vector object and on this vector object we call the overloaded operator[] once more by calling it with argument 'cc' as column index ( as we would do with a std::vector object[index] )

With this the code certainly looks elegant and professional :)

like image 25
ggulgulia Avatar answered Nov 14 '22 03:11

ggulgulia