Having trouble in C++ Creating vector of pointers or map of Pointer values

To give some context, I am trying to create a map or a vector that looks like either of these: I have tried both, and can't seem to get it working.

vector<Player*,Player*> regionOwners; 
map<int, vector<Player*>> regionOwners;

Essentially I have regions in a game that correspond to integer values (0-10) Most regions can only have 1 owner (the player), however certain ones can also have 2 owners. This is the reason I want to have a vector, so that I can go regionOwners[regionNumber][0] or regionOwners[regionNumber][1] and either access a playerObject or a nullptr. If possible, I want to set the vector size to a max of 2.

I essentially want to store examples like this:

1 --> [PlayerPtr*]
2 --> [Player1Ptr*, Player2Ptr*]
3 --> [nullptr, nullptr]
4 --> [nullptr]
5 --> [Player1Ptr*, nullptr]
6 --> [nullptr, Player1Ptr*]

I cant seem to initialize my vector or map with nullptrs to indicate that the region does not have an owner.

for(int i=0; i< gameMap->getVertexCount(); i++) {
    if(gameMap->getVertex(i)->getData() == "outer") {
        regionOwners[i].push_back({nullptr , nullptr}); // vector style
    }
    else if (gameMap->getVertex(i)->getData() == "inner") {
        regionOwners.insert({i, {nullptr}});
    }
 }

I have tried all variations of maps and vectors. Im stumped.

        regionOwners[i]= {nullptr , nullptr}; // vector
        regionOwners.insert({nullptr, nullptr}); // vector
        map<int,vector<Player*>> something;
        something.insert(i, {nullptr, nullptr});
        regionOwners[i].push_back({nullptr , nullptr}); 
        regionOwners.push_back(i ,{nullptr , nullptr}); 

I was wondering what suggestions anyone has on how to solve my issue, as I know I'm likely going about this wrong. I thought of using a vector of a linkedlist so that I could just go from one node of a Player to the other once I have resolved the region. Thanks.

2 answers

  • answered 2018-11-08 07:19 lubgr

    First of all, this

    vector<Player*,Player*> regionOwners; 
    

    can't work as you intend it. std::vector stores scalar entries (and the second template argument is an allocator which you probably don't want to specify right now), so this declaration will be rejected by the compiler.

    If possible, I want to set the vector size to a max of 2

    That makes it a std::pair, not a std::vector. You can try one of these:

    std::vector<std::pair<Player*, Player*>> regionOwnersVec;
    std::map<int, std::pair<Player*, Player*>> regionOwnersMap;
    

    Now you can use them e.g. like the following.

    // allocates memory if necessary:
    regionOwnersVec.push_back({nullptr, nullptr});
    
    // ... or set some predefined size, which allocates and default-initializes:
    regionOwnersVec.resize(42);
    
    // ... which enables indexing the vector:
    regionOwnersVec[10] = {nullptr, nullptr};
    

    Or alternatively for the std::map instance,

    regionOwnerMap[10] = {nullptr, nullptr};
    

    As a side note, if you want the container to own the instances, prefer std::unique_ptr together with std::make_unique instead of raw pointers.

  • answered 2018-11-08 07:24 Yksisarvinen

    std::vector<std::array<Player*, 2>>
    

    will work as you wanted, i.e. it only allows at most 2 region owners and you can use double operator[]:

    std::vector<std::array<Player*, 2>> regionOwners (11, {nullptr, nullptr});
    if(regionOwners[5][1]) {
        //blahblah
    }
    

    For convienience, you can create a name alias:

    using RegionOwners = std::vector<std::array<Player*, 2>>;
    RegionOwners regionOwners (11, {nullptr, nullptr});