By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,433 Members | 1,827 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,433 IT Pros & Developers. It's quick & easy.

std::find_if in vector

P: n/a
I would like to search in a vector depending on "a" or "a and b"
without the overhead of creating a Foo object or another predicate
class.

Is that possible? Using a member function pointer or a global static
function?
Right now I have this, but I don't like it.

------------------------------Example
code----------------------------------------------
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>

class Foo {

public:
Foo(int aa, int bb, int cc):a(aa),b(bb),c(cc) {}

bool operator()(const Foo& f) {
return (GetA() == f.GetA() &&
GetB() == f.GetB() &&
GetC() == f.GetC());
}

inline int GetA() const {return a;}
inline int GetB() const {return b;}
inline int GetC() const {return c;}

private:
int a,b,c;
};

class Foo_eq_a : public std::unary_function<Foo, bool{
public:
explicit Foo_eq_a(int aa):a(aa) {}

bool operator() (const Foo& f) const
{
return (f.GetA() == a);
}
private:
int a;
};
class Foo_eq_ab : public std::unary_function<Foo, bool{
public:
explicit Foo_eq_ab(int aa, int bb):eq_a(aa),b(bb) {}

bool operator() (const Foo& f) const
{
return (eq_a(f) && f.GetB() == b);
}
private:
Foo_eq_a eq_a;
int b;
};

int main()
{
std::vector<Foofoos;

foos.push_back(Foo(1,1,1));
foos.push_back(Foo(1,2,2));
foos.push_back(Foo(1,2,3));
std::vector<Foo>::const_iterator citer;
citer = std::find_if(foos.begin(), foos.end(), Foo(1,2,3));
if (citer != foos.end())
std::cout << "operator() hit, okay" << std::endl;

citer = std::find_if(foos.begin(), foos.end(), Foo(1,2,4));
if (citer == foos.end())
std::cout << "operator() no hit, okay" << std::endl;
citer = std::find_if(foos.begin(), foos.end(), Foo_eq_ab(1,2));
if (citer == ++foos.begin())
std::cout << "position 1, okay" << std::endl;

system("Pause");
}

----------------------------------
Any suggestions?
Thanks
Nov 5 '08 #1
Share this Question
Share on Google+
5 Replies


P: n/a
Sam
ei*************@googlemail.com writes:
I would like to search in a vector depending on "a" or "a and b"
without the overhead of creating a Foo object or another predicate
class.

Is that possible? Using a member function pointer or a global static
function?
Use std::ptr_fun to turn your global static function into a suitable
function object.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEABECAAYFAkkRiwIACgkQx9p3GYHlUOKxMwCeLnLlbbFolN N+/LekQI21r/N1
9uYAn160phJeQi1S8oyI6qM2VfcA1Brx
=uZ/K
-----END PGP SIGNATURE-----

Nov 5 '08 #2

P: n/a
eiji.anonrem...@googlemail.com a écrit :
I would like to search in a vector depending on "a" or "a and b"
without the overhead of creating a Foo object or another predicate
class.
Maybe a lambda?

With:
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
namespace bl = boost::lambda;

This:
std::find_if(f.begin(), f.end(), (bl::bind(&Foo::GetA, bl::_1) == 1)
&& (bl::bind(&Foo::GetB, bl::_1) == 2));
could replace:
std::find_if(foos.begin(), foos.end(), Foo_eq_ab(1,2));

Nov 5 '08 #3

P: n/a

Use std::ptr_fun to turn your global static function into a suitable
function object.
This is not possible, since you can not pass in arguments, from what I
know.

To turn this:
citer = std::find_if(foos.begin(), foos.end(), Foo_eq_ab(1,2));

into
class Foo {
....
public:
static bool eq_ab(const Foo& f) {return false}
....
};

There is no possibility to pass "1,2".

??
Nov 5 '08 #4

P: n/a
Maybe a lambda?
>
With:
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
namespace bl = boost::lambda;

This:
std::find_if(f.begin(), f.end(), (bl::bind(&Foo::GetA, bl::_1) == 1)
&& (bl::bind(&Foo::GetB, bl::_1) == 2));
could replace:
std::find_if(foos.begin(), foos.end(), Foo_eq_ab(1,2));
Two reasons why not:
- boost is not an option :-/
- I wan't to encapsulate (x == y && z == y ...) in one place. Using
this approach, I would again have to change lot's of places when
search pattern changes a bit. The search pattern and the call should
be clean seperated as far as possible.
Nov 5 '08 #5

P: n/a
Sam
ei*************@googlemail.com writes:

>Use std::ptr_fun to turn your global static function into a suitable
function object.
This is not possible, since you can not pass in arguments, from what I
know.

To turn this:
citer = std::find_if(foos.begin(), foos.end(), Foo_eq_ab(1,2));

into
class Foo {
...
public:
static bool eq_ab(const Foo& f) {return false}
...
};

There is no possibility to pass "1,2".
static bool Foo_eq_b(int n)
{
return Foo_eq_a_b(1, 2, n);
}

std::find_if(foos.begin(), foos.end(), std::ptr_fun(Foo_eq_b));

… or whatever.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEABECAAYFAkkSKugACgkQx9p3GYHlUOKZNwCfceupIUPeMG 6bpdgnU2GvEAHZ
x1UAniHYA5+bfyfmn6EkVQKy8LIG8Aia
=kF5q
-----END PGP SIGNATURE-----

Nov 5 '08 #6

This discussion thread is closed

Replies have been disabled for this discussion.