Igor
Igor

Reputation: 6255

How to remove an object from std::vector?

ALL,

Consider following code:

class CPlayer
{
public:
    CPlayer(bool new) { m_new = new; };
    bool IsNewPlayer() { return m_new; }
private:
    bool m_new;
};

int main()
{
    std::vector<CPlayer> players_pool;
    players_pool.push_back( false );
    players_pool.push_back( false );
    players_pool.push_back( true );
    players_pool.push_back( false );
}

Now what I'm looking for is to remove the players which has m_new as true.

Is it possible to do something like this:

players_pool.erase( std::remove( players_pool.begin(), players_pool.end(), players_pool.at().IsNewPlayer() ), players_pool.end() );

Now everywhere the examples given are for simple integers and not for the class objects.

Is there an easy way to perform such an operation?

And I need it to work in MSVC 2010 and XCode 4 with 10.6 SDK.

Note: The code given is a simplified version of the actual code I'm working on. Class CPlayer has a lot more fields than I put here but they are not relevant to this post.

Thank you.

P.S.: I found this but my question here is if it will work on OSX. My remover looks like this:

struct Remover : public std::binary_function<CPlayer,void,bool>
{
public:
    bool operator()(const CPlayer &player) const
    {
        return player.IsNewPlayer();
    }
};

Upvotes: 1

Views: 264

Answers (2)

Stack Overflow is garbage
Stack Overflow is garbage

Reputation: 247999

Yes, it is possible. The standard library provides std::remove, which removes objects which are equal to some specified value (using the == operator), and it has std::remove_if, which, instead of a value, takes a function which is called on the object, and if it returns true, it indicates that the object should be removed. So simply write a function which defines the condition you want, and use that:

players_pool.erase( std::remove_if(
  players_pool.begin(),
  players_pool.end(),
 [](const CPlayer& p){ return p.IsNewPlayer(); }),
 players_pool.end() );

Note, I used a lambda for the function passed to remove_if. If your compiler doesn't support that yet, you can simply define the function separately, either as a function (with the signature bool func(const CPlayer&);, or a function object with an bool operator()(const CPlayer&)

Upvotes: 1

Manu343726
Manu343726

Reputation: 14174

Simply use std::remove_if and a lambda function as predicate:

players.erase( std::remove_if( players.begin() , 
                               players.end() , 
                               [](const Player& player) { return player.IsNewPlayer(); } 
                              ) );

Lambdas are supported by VC10 (VS2010 C++ compiler).

In XCode you are using Clang? It supports lambda expressions too.

On the other hand, if your compiler not supports C++11 lambdas, your functor is the correct way.

Upvotes: 0

Related Questions