Hi,
What I'd like to do is iterate over a list of objects, checking the return value of a member function for a particular value.
Some groundwork:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
#include <assert.h>
#include <list>
class SampleObject
{
public:
typedef unsigned int ObjectID;
SampleObject( ObjectID id ) : m_ID(id) {}
ObjectID getID() const { return m_ID; }
private:
ObjectID m_ID;
};
int main()
{
std::list<SampleObject*> objList;
objList.push_back(new SampleObject(0));
objList.push_back(new SampleObject(1));
objList.push_back(new SampleObject(2));
objList.push_back(new SampleObject(3));
std::list<SampleObject*>::iterator iter;
SampleObject::ObjectID id;
...
return 0;
}
|
This is simple enough using a for loop:
1 2 3
|
id = 0;
for( iter = objList.begin(); iter != objList.end() && (*iter)->getID() != id; iter++);
assert( iter != objList.end() && (*iter)->getID() == id );
|
But, what I'd really like to use is std::find_if (maybe just out of curiosity more than anything else). I've come up with two ways to do this, neither optimal in my opinion.
First, I wrote my own templates to accomplish it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
template <typename Ret, typename Obj>
class mem_fun_equal_t
{
public:
mem_fun_equal_t(Ret (Obj::*func)(), Ret val) : m_Func(func), m_Val(val) {}
bool operator()(Obj* object) { return (object->*m_Func)() == m_Val; }
private:
Ret (Obj::*m_Func)();
Ret m_Val;
};
template <typename Ret, typename Obj>
mem_fun_equal_t<Ret, Obj> mem_fun_equal(Ret (Obj::*func)(), Ret val)
{
return mem_fun_equal_t<Ret, Obj>(func, val);
}
|
then
1 2 3
|
id = 2;
iter = find_if(objList.begin(), objList.end(), mem_fun_equal(&SampleObject::getID, id));
assert( iter != objList.end() && (*iter)->getID() == id );
|
However, I'd really rather find something like this in the STL rather than write it myself.
More poking around in STL documentation resulted in finding mem_fun (I subsequently renamed my solution above as it made more sense). With this, I can do exactly what I want....as long as SampleObject has an additional function:
1 2 3
|
...
bool hasID(ObjectID id) const { return m_ID == id; }
...
|
then
1 2 3
|
id = 1;
iter = find_if(objList.begin(), objList.end(), std::bind2nd(std::mem_fun(&SampleObject::hasID), id) );
assert( iter != objList.end() && (*iter)->getID() == id );
|
So, finally on to my question. Is there a) an STL version of my second solution or b) a combination of STL adapters to accomplish my goal without adding an additional function to the class?
My curiosity is piqued, and my brain won't rest until I find a solution to satisfy it. Any ideas?
Thanks,
Keith