std::find_if in vector

  • Thread starter eiji.anonremail
  • Start date
E

eiji.anonremail

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<Foo> foos;

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");
}
 
E

Eric.Malenfant

(e-mail address removed) 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));
 
E

eiji.anonremail

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

??
 
E

eiji.anonremail

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.
 

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,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top