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]; ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.