Reputation:
I want to get a pointer from vector's element which has Fd
property set on desired value. Right now I am using this ugly code:
User* Game::GetUser(int fd)
{
for(auto& v : users)
if (v.Fd == fd)
return &v;
return nullptr;
}
How can I change this code to be more similar to this:
void Game::RemoveUser(int fd)
{
users.erase(remove_if(begin(users), end(users), [fd](User const& u)
{
return u.Fd == fd;
}), end(users));
}
Or maybe there are other, much better ways to code this?
Upvotes: 1
Views: 96
Reputation: 44238
How can I change this code to be more similar to this
Just use std::find_if
with the same predicate:
User* Game::GetUser(int fd)
{
auto it = find_if(begin(users), end(users), [fd](User const& u)
{
return u.Fd == fd;
}));
return it == end(users) ? nullptr : &*it;
}
to avoid code duplication you can use result of find_if
for erase as well:
users_type::iterator findUser( int fd)
{
return find_if(begin(users), end(users), [fd](User const& u)
{
return u.Fd == fd;
}));
}
User* Game::GetUser(int fd)
{
auto it = findUser( fd );
return it == end( users ) ? nullptr : &*it;
}
void Game::RemoveUser(int fd)
{
auto it = findUser( fd );
if( it != end(users) )
users.erase( it );
}
you may consider to use different container if such operations has to happen quite often, as both std::find_if
and std::remove_if
are linear to number of elements. Or you may want to keep users
sorted and use std::equal_range()
instead of std::find_if()
which is log(N)
, but you would need to use findUser
to find proper location to insert or use std::sort
after insertion(s).
Upvotes: 3