Connecting Tech Pros Worldwide Forums | Help | Site Map

std::find_if in vector

eiji.anonremail@googlemail.com
Guest
 
Posts: n/a
#1: Nov 5 '08
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

Sam
Guest
 
Posts: n/a
#2: Nov 5 '08

re: std::find_if in vector


eiji.anonremail@googlemail.com writes:
Quote:
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-----

Eric.Malenfant@gmail.com
Guest
 
Posts: n/a
#3: Nov 5 '08

re: std::find_if in vector


eiji.anonrem...@googlemail.com a écrit :
Quote:
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));

eiji.anonremail@googlemail.com
Guest
 
Posts: n/a
#4: Nov 5 '08

re: std::find_if in vector



Quote:
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".

??
eiji.anonremail@googlemail.com
Guest
 
Posts: n/a
#5: Nov 5 '08

re: std::find_if in vector


Maybe a lambda?
Quote:
>
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.
Sam
Guest
 
Posts: n/a
#6: Nov 5 '08

re: std::find_if in vector


eiji.anonremail@googlemail.com writes:
Quote:

Quote:
>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-----

Closed Thread