I'm making a simple crime sim game.
Throughout it I keep doing the same thing over and over:
// vector<Drug*> drugSack;
for (unsigned int i = 0; i < this->drugSack.size(); i++)
this->sell(drugSack[i]);
Just one example. I hate having all these for loops all over the place omg QQ, anyway to do something like:
drugSack->DoForAll((void*)myCallBack);
I'm not well versed in the STL.
Well, first I'm confused: what's
sell
? Is it meant to be a member function of some class, you need to make drugSack that class, in which case you can do something like the following --Something like
for_each
to iterate overdrugSack
, combined withmem_fun
to getsell
:If sell is just an ordinary function, you can just put it in the third argument of for_each.
You could use std::for_each from the STL which applies a function to a range. See the following description: http://www.cplusplus.com/reference/algorithm/for_each/.
You will also need to use std::mem_fun or std::mem_fun_ptr to obtain the member function of your class.
For more advanced cases, have a look at Boost Bind which provides an advanced binder for creating function objects.
Time to start knowing the stl algorithms:
The idea is to create an object, called a "functor", that can do a certain action for each of the elements in the range
drugSack.begin(), drugSack.end()
.This functor can be created using stl constructs like
mem_fun_ptr
, resulting in a functor taking aThisClass*
and aDrug*
argument, and a wrapper around it that will substitute/bind theClass*
forthis
.Honestly, C++ is currently pretty bad at this kind of stuff. It can definitely do it, as outlined in xtofl's answer, but it's often very clumsy.
Boost has a for-each macro that is quite convenient:
Or perhaps Boost.Bind, though this is slightly more complex, it reads very nice for your case:
Bind will make a functor that calls the member function of
ThisClass
,sell
, on the instance of the class pointed to bythis
, and will replace_1
with the argument it gets fromfor_each
.The most general method is with lambda's. Boost has a lambda library. I won't include samples here because for your specific case boost bind works, and the lambda's would be the same code. That said, lamba's can do much more! They basically create in-place functions (implemented as functors), but are much more complex to learn.
Both for-each and bind are far cleaner than the "standard" C++ methods, in my opinion. For now, I'd recommend, in order: for-each, bind, standard C++, lambda's.
In C++0x, the next C++ standard, all this will be nice again with built-in lambda support:
Or the new range-based for loops:
But we must wait a couple years before this is an option. :( Also, I think the range-based for-loop is the easiest thing to read. This is why I recommend boost for-each, because it mimics this behavior and syntax (mostly).
Also, totally unrelated: the style where you include
this->
before everything is, in my experience, generally considered bad practice. The compiler will do it for you, all you're doing is cluttering up your code and introducing the chance of mistakes. Things read much better without it.For the simple of case of looping through an entire container, I'd just write the loop. It's unfortunately long-winded, but not prone to mistakes if you always write it the same way. I always write such loops as follows:
(or
const_iterator
where appropriate).You could try BOOST_FOREACH as an alternative.