1

I have a static integer variable Game::numPlayers, which is read in as an input from user. I then have the following class defined as such:

class GridNode
{
private:
    /* Members */
    static const int nPlayers = Game::numPlayers;
    std::vector<Unit> units[nPlayers];

    //...
};

This won't compile ("in-class initializer for static data member is not a constant expression").

I obviously cant just assign the array size of Game::numPlayers, and I also tried not initializing it and letting a constructor do the work, but that didn't work either.

I don't understand what I'm doing wrong here and what else I could possibly do to get this to work as intended.

I'm just copying a value, how is that any different from static const int nPlayers = 8 which copies the value 8 into nPlayers and works?

Edit:

To clarify, I choose to have an array of vectors because I want each node to have a quick-access container of units, but one container for each user/player so as to distinguish which units belong to which player within each node (e.g. index 0 of the array = player 1, index 1 = player 2, index 2 = player 3, and so on), otherwise I would just have one vector or a vector of vectors. I thought a map might work, but I thought an array of vectors would be faster to access and push into.

Also, Game::numPlayers is read in as a user input, but only read and assigned once within one game loop, but if I close/restart/play a new game, it needs to read in the user input again and assign it once.

7
  • 1
    Shouldn't you take an approach when nPlayers and units is only declared/initialised after the user input at runtime, not at compile time? Commented Jul 5, 2015 at 1:49
  • Just to be sure, do you really want an array of vectors? Or do you really want one vector to hold nPlayers items? From the code you posted, the approach would be to use std::vector<std::vector<Unit>>, not an array of vectors. Commented Jul 5, 2015 at 2:05
  • I just made an edit to clarify. Commented Jul 5, 2015 at 2:11
  • @awar a vector of vectors is equivalent to your array of vectors. On construction, just size the vector appropriately. Commented Jul 5, 2015 at 2:37
  • How does this address my issue of having each vector distinct to each Player as I said in my edit? Specifically where each index "i" in my array of vectors would represent the vectors of units for each Player "i"? Commented Jul 5, 2015 at 2:41

2 Answers 2

1

I don't see why you need to use an array of std::vector if the number of elements will be obtained at runtime.

Instead, create a std::vector<std::vector<Units>> and size it appropriately on construction. if you need to reset the size, have a member function resize the vector.

Example:

class GridNode
{
    private:
        /* Members */
        std::vector<std::vector<Unit>> units;

    public:
        GridNode(int nPlayers=10) : units(nPlayers) {}

        std::vector<Unit>& get_units(size_t player) 
        { return units[player]; }  // gets the units for player n

        void set_num_players(int nPlayers) 
        {  units.resize(nPlayers); }  // set the number of players

        int get_num_players() const { return units.size(); }
 };

 int main()
 {
     int numPlayers;
     cin >> numPlayers;
     //...
     GridNode myGrid(numPlayers); // creates a GridNode with 
                                    // numPlayers vectors.  
     //...
     Unit myUnit;
     myGrid.get_units(0).push_back(myUnit); // places a Unit in the 
                                            // first player
 }

Also, it isn't a good idea to have extraneous variables tell you the vector's size. The vector knows its own size already by calling the vector::size() function. Carrying around unnecessary variables that supposedly gives you this information opens yourself up for bugs.

Sign up to request clarification or add additional context in comments.

1 Comment

Ah, I didn't know you could initialize the size of the vector like that, I was trying to do something like std::vector<std::vector<Unit>> units(8);, but that wasn't working. Thanks a ton!
1

Only integral constant expressions are allowed as array sizes in array declarations in C++. A const int object initailized with something that is not an integral constant expression (your Game::numPlayers is not, since it is read from the user), does not itself qualify as integral constant expression.

The bottom line here is that regardless of how you slice it, it is not possible to sneak in a run-time value into an array declaration in C++. C++11 does support some semblance of C99-style Variable Length Arrays, but your case (a member array) is not covered by it anyway.

If the array size is a run-tuime value, use std::vector. In your case that would become std::vector of std::vectors.

1 Comment

What if Game::numPlayers is only assigned once? It has to read it in as an input, but it is only assigned once. How could I restructure my code then? Also, if you look at my edit, I don't think a vector of vectors would accomplish what I want.

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.