Predicates for find_if() and friends with more parameters

U

Urs Thuermann

Functions like std::find_if() and std::remove_if() need a predicate
that takes an argument from the range these functions iterate over and
returns a bool. Many tutorials and docs show how one can find, e.g.,
the first odd int or remove all odd ints from a container, using a
predicate "bool isodd(int)".

However, I often need to iterate through a container and compare one
member of each element to some value, like this

User *find_user(string login)
{
for (it = users.begin(); it != users.end(); ++it) {
if (it->login == login)
break;
...
}

Functions like find_if() or remove_if() look elegant in many cases but
are there versions which call predicates taking an additional
argument, e.g. a login name to compare with?

urs
 
M

Michael DOUBEZ

Functions like std::find_if() and std::remove_if() need a predicate
that takes an argument from the range these functions iterate over and
returns a bool.  Many tutorials and docs show how one can find, e.g.,
the first odd int or remove all odd ints from a container, using a
predicate "bool isodd(int)".

However, I often need to iterate through a container and compare one
member of each element to some value, like this

        User *find_user(string login)
        {
                for (it = users.begin(); it != users.end(); ++it) {
                        if (it->login == login)
                                break;
                ...
        }

Functions like find_if() or remove_if() look elegant in many cases but
are there versions which call predicates taking an additional
argument, e.g. a login name to compare with?

There are many solutions:

- classical solution: use a class
class IsLoginEqualTo
{
public:
IsLoginEqualTo( string login): _login(login){}

bool operator()(User const & user) const
{
return user.login == _login;
}
private:
string _login;
};

Then:
std::find_if(begin(),end(),IsLoginEqualTo(login));

- use bind (boost or std::tr1):
std::find_if(begin(),end(), std::equal_to<string>(),bind(&User::login,
_1),login);

Note that boost provides lambda bindings whic allows writing:
bind(&User::login, _1) == login

- use C++0x lambda:
std::find_if(begin(),end(),[&login](const User& user) { return
user.login == login; });
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top