На вашем месте я бы сделал это так:
в 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
в 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
}
Естественно, это усложнит способ доступа к элементам, но это легко сделать, перегружив оператор (), который возвращает ссылку на позицию, к которой вы хотите получить доступ. Обратите внимание, что публично наследуя std :: vector, мы унаследовали все их операторы, а также функции-члены и переменные Следовательно, мы также унаследовали перегруженный оператор [] в классе std :: vector. Следовательно, мы можем получить доступ к любому элементу перегруженным оператором, как показано ниже:
template<class T>
T& Game<T>::operator()(int rr, int cc){
return this->operator[](rr)[cc];
}
В приведенном выше операторе return первая часть вызывает перегруженный оператор [] с аргументом rr, который возвращает векторный объект, и для этого векторного объекта мы снова вызываем перегруженный оператор [], вызывая его с аргументом 'cc' как индекс столбца (как мы сделали бы с объектом std :: vector [index])
При этом код, безусловно, выглядит элегантно и профессионально:)