-1

I've been studying/reading about C++ for a long time now, but I've hardly written any. So despite knowing a good amount about modern C++ practice, I still don't have good design patterns down.

Here's my issue: Let's say I have a class Board, which represents a game board (i.e., chess, go, etc). The underlying storage for this board is a std::array.

There's another class GameRunner which owns a Board and is in charge of running the rules of the game, keeping score, etc.

The game board has a size defined by the user. In my head GameRunner was simply declared as such: GameRunner::GameRunner(unsigned size), and then size parameter is likewise passed into the Board that is declared: Board::Board(unsigned size).

The problem is that std::array must have a size statically determined. So I can't have a member variable of std::array because I don't know at compile time what the size would be. I thought I could make a std::unique_ptr as my member, and then have that point to a dynamically created array, but of course you need to define std::unique_ptr<std::array<???????>> where the question marks denote how I obviously don't know the size of this array.

So my solution was to make Board have a template to pass in the size... so GameRunner would have a Board<size>, but then of course GameRunner needs to have a template as well, so now it's templates all the way down...

So what do I do here? Templates all the way down? Use a variable-size container even though the size should never change? I feel like there's something incredibly trivial I'm missing...

bob
  • 1,879
  • 2
  • 15
  • 27
  • You could make the Board have a vector size ... trade an unmeasurable runtime speed difference for simple code and faster development time – M.M Sep 22 '16 at 05:55

2 Answers2

2

You should use std::vector<T> instead of std::array<T, N>.

user703016
  • 37,307
  • 8
  • 87
  • 112
Alexey Guseynov
  • 5,116
  • 1
  • 19
  • 29
  • I'm aware std::vector is a solution. But for the sake of learning, I want to know if there's a better way to create a fixed-size stack-based array with size defined at runtime instead of comiletime. If there is no way and `std::vector` is the only way, then I'll live with that. – bob Sep 22 '16 at 05:28
  • It is allowed to have stack-based arrays with runtime defined size, but you can't have them in objects because then object's size will become variable and that greatly complicates things. For example you won't be able to make an array of such objects. There is also another consideration: stack is usually much smaller than heap, so it is better to allocate big objects on a heap. So you can't have that array on stack and you can't have it directly inside the Board class. And if it is on a heap, then std::vector is the most natural and easy solution. – Alexey Guseynov Sep 22 '16 at 05:54
  • 2
    @AlexeyGuseynov "It is allowed to have stack-based arrays with runtime defined size" IINM, strictly speaking, that's allowed in C99 but not C++. It's true that `g++` supports it, but it's a non-portable compiler-specific language extension (see [here](http://stackoverflow.com/questions/20010716/gnu-compilers-vs-visual-studio-on-arrays-allocated-w-length-constant-w-in-a-sc)). – Ami Tavory Sep 22 '16 at 06:35
  • @andy if you really want your data to be stack-based you could use something like LLVM's [SmallVector](http://llvm.org/docs/ProgrammersManual.html#llvm-adt-smallvector-h). Then for reasonably small sized boards your data can be on the stack and larger boards will be dynamically allocated. – Chris Drew Sep 22 '16 at 09:04
2

There was a proposal to add a container for this situation to the C++ standard--one that would have its size determined when it was constructed, and never change afterward. That was rejected, but it's fairly easy to write your own if you want to. Alternatively, just use std::vector, and live with the fact that it has functionality you don't need or care about (but it's unlikely to cause a problem either).

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111