c++ vector::erase with class object iterator not e

2019-08-31 00:35发布

问题:

I know that this question is similar to others, but I looked here and here and neither of these solved my problem. Everything I have been able to find says that the following code should work. The vector I use for testing has elements with names superman, batman, and spiderman. I can't remove any more code for the example to make sense I don't think.

class Room{
  vector<User> users;
  users = {{superman, pass}, {batman, pass}, {spiderman, pass}};

public:
  vector<User> Room::getUsers() {return users;}
};

class User{
  string username;
  string pass;
};



    // Find the room. Once found, scan through the users
    // Once the user is found, remove them from the vector
    for(roomIt = rooms.begin(); roomIt < rooms.end(); roomIt++) {
      if (roomIt->getName().compare(roomName) == 0) {
        for (useIt = roomIt->getUsers().begin(); useIt < roomIt->getUsers().end(); useIt++) {
          if (useIt->getName().compare(username) == 0) {
            useIt = roomIt->getUsers().erase(useIt);
            const char * msg = "OK\r\n";
            write(fd, msg, strlen(msg));
            return;
          }
        }
      }
    }

The room object has a vector of type user. roomIt->getUsers() returns the vector of users in a room. The innermost if statement doesn't do anything, however. To debug, I have a vector of 3 Users. When using gdb, I can see that useIt = roomIt->getUsers().erase(useIt) causes the iterator to move from the second element in the vector to the third element. However, the vector does not change. There were 3 elements beforehand, and there are 3 elements afterwards as well.

回答1:

As user2328447 speculated in the comments your getUsers is returning by value, not reference. So every single time you call it, you get a completely unrelated vector (same values, but stored separately); even your loop construct is wrong (it's comparing the .begin() from one copy of the vector to the .end() of a separate copy).

If you want to be able to mutate the instance's vector from the caller, you must return a reference, changing:

vector<User> Room::getUsers() {return users;}

to:

vector<User>& Room::getUsers() {return users;}
            ^ return reference, not value