Thursday, April 06, 2006

C++ : In a bind with function objects part I

So, here’s how it goes. I needed to perform an operation on each member of a list of pointers to class A. I’d always used for-loops to iterate though containers in the past. Also a lot of the functionality I needed in order to do the operation wasn't part of class A but of class B, which held the container of class A pointers as a member so this made sense. A little code may shed some light on things at this point:


class A
{
public:
std::string &GetName() const;
const int GetThreshold() const;
...
};

typedef vector<A *> APtrContainer;

class B
{
public:
void Update();

private:
Control *GetControlByName(std::string);
Graphic &GetGraphic() const;
...
APtrContainer m_APCollection;
};


Still, my desire to use std::for_each was strong, pah! to for-loops I thought, there must be a way!


I thought back to how the old, ugly code would have looked, something like this I guessed...


void B::Update()
{
Graphic &graphic = GetGraphic();

for(APtrContainer::iterator it = m_APCollection.begin(); it!=
m_APCollection.end(); ++it)
{
std::string &name = it->GetName();
Control *control = GetControlByName(name);
// can return NULL
if(control)
{
bool value =
control->GetCurrentValue() > it->GetThreshold();
graphic.doSomething(value);
}
}
}


So, now to refactor using std::for_each, I thought. I know I need to pass it a function object so let’s write that first. Perhaps I was being rash but fools rush in where angels fear to tread, so in I rushed …


Witness the resulting mess in part II coming soon...

No comments: