0

I am trying to compile this code:

class OthelloState {
public: // constructor 

    Othello(int r, int c);

/* other stuff */

private: // private data

    const int rows;

    const int columns;

    int board[rows][columns];
}

I keep ending up with:

OthelloState.h:109: error: invalid use of non-static data member 'OthelloState::rows'
OthelloState.h:115: error: from this location
OthelloState.h:115: error: array bound is not an integer constant
OthelloState.h:112: error: invalid use of non-static data member 'OthelloState::columns'
OthelloState.h:115: error: from this location
OthelloState.h:115: error: array bound is not an integer constant

I assume that this means I have to make rows and columns static. But if I make them static, I cannot initialize either with from a constructor, the way I have to for this project...

Is there some other way I can do this?

PS: I know that in real Othello, the board is a square 8 by 8 grid...But after considering how long it would take the computer to generate the next best move on a partial 8 by 8 grid, we are not going to play with "real" Othello board (i.e. no predefined board sizes).

3
  • Not static, but "constant and determinable at compile-time". Commented Nov 2, 2011 at 2:49
  • Don't you need to initialize rows and columns? They are consts. Commented Nov 2, 2011 at 4:05
  • @muntoo I initialized them in the constructor in the cpp file. Commented Nov 2, 2011 at 16:49

4 Answers 4

3

In C++, variable length arrays are not allowed. board[][] needs to know both of its dimensions at compile time. You can use vector<vector<int> > board;, if you want to initialize row and col at runtime.

class OthelloState {
public:
    OthelloState(int r, int c);

private: // private data
    const int rows;  // should be 'unsigned int'
    const int columns;

    vector<vector<int> > board;  
};

Other solution:

Suppose you know rows and cols at compile time then you can use template. That is as good as initializing row and col in constructor.

template<unsigned int row, unsigned int col>
class OthelloState {
public:
...
private:
  int board[row][col];
};

Usage:

  OthelloState<8,8> obj;
  OthelloState<10,10> obj;
Sign up to request clarification or add additional context in comments.

4 Comments

Could I use your template method without knowing rows and columns at compile time?
@MatthewD, No. The templates can be used only with compile-time information.
vector<vector<int> > board[rows][columns];: Is that syntax C++11?
@EmileCormier, it was a bad copy paste. Thanks & Edited.
0

if it's always 8x8, then constants are a minimal solution. here's one way to declare it:

class OthelloState {
    // ...
private:
    enum { rows = 8, columns = 8 };
    int board[rows][columns];
};

Comments

0

But after considering how long it would take the computer to generate the next best move on a partial 8 by 8 grid, we are not going to play with "real" Othello board (i.e. no predefined board sizes).

I deduce from that sentence that you're working on a homework assignment. If that's the case, then it might not be possible/practical for you to use Boost.MultiArray (unless your instructor advised you that it's okay to use Boost).

That leaves vector< vector<int> > which are a PITA to initialize properly. Before you can even use vector< vector<int> >, you have to loop through each inner vector and resize it.

Boost.MultiArray is basically just an overglorified wrapper around a 1D array of data. I therefore propose a third alternative: Roll up your own 2D wrapper around a flat one-dimensional vector. You can overload operator() to mimic the [][] behavior of 2D arrays:

int operator()(size_t row, size_t col) {/*compute index into 1D array*/}

I posted an example of this kind of wrapper here.

Comments

0

You're trying to dynamically define the size of a compile-time, fixed size array at runtime. You will need to dynamically allocate the memory. You also need your constructor to have the same name as your class

class OthelloState {
public: // constructor 

OthelloState(int r, int c)
{ 
   board = new int[r];
   for(int i = 0; i < r; i++)
   {
      board[i] = new int[c];
   }
}


/* other stuff */

private: // private data

   const int rows;

   const int columns;

   int **board;
};

Make sure you have matching deletes for all your news in a destructor if you use this method, though

4 Comments

I do not recommend this approach. You're just asking for dangling pointer problems. You need to provide a copy constructor and copy assignment so that deep copies are made (or alternatively, make the copy-ctor and assignment private to make the class non-copyable).
vector< vector<int> > does exactly the same thing as this solution without all the memory management pitfalls.
Yes, proper memory management in required, but it's a solution for creating a primitive 2-d array when the size is not known until runtime. I agree that vector< vector<int> > is at least a safer way to create some 2-dimensional matrix, but I don't think it's the best answer to the question as it's stated.
shouldn't it be board[i] = new int[c]; ?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.