The "solution" below compiles but it is not what I want. I would like to pass the put
member function to for_each
and not *this
. Using boost is NOT an option. Can this be solved within C++03?
#include <algorithm>
#include <functional>
#include <vector>
using namespace std;
class Wheel { };
class Car {
public:
void process(const vector<Wheel>& wheel) {
for_each(wheel.begin(), wheel.end(), *this);
}
void operator()(const Wheel& w) { put(w); }
private:
void put(const Wheel& w) { }
};
int main() {
vector<Wheel> w(4);
Car c;
c.process(w);
return 0;
}
Yes it can, using a combination of the mem_fun
and bind1st
templates:
void process(const vector<Wheel>& wheel) {
for_each(wheel.begin(), wheel.end(), bind1st(mem_fun(&Car::put), this));
}
The call to mem_fun
creates a new function object that takes in two arguments - a Car*
to act as the receiver and a Wheel
, then calls put
with the first parameter as the receiver and the second parameter as the argument. Calling bind1st
then locks the receiver object as first parameter of this function in place.
However, I think you will need to make one small change to this code to get it to work. The bind1st
adapter doesn't play well with functions that take their arguments by const reference, so you might need to change put
so that it takes a Wheel
by value rather than by reference.
You can use mem_fun_ref: see here.
mem_fun_ref
should work in your case where you have vector of objects:
for_each(wheel.begin(), wheel.end(), mem_fun_ref(&Wheel::put));
Note that the above example changes put
to be a member of Wheel and not Car. It should give you an idea of how to use it though.
Use mem_fun
if you have a vector of pointers to an object
Sure- you can just write your own equivalent of boost::mem_func. TR1 has one too. It's a little repetitive if you want increasing numbers of arguments, but not conceptually hard.
template<typename T, typename mem_func_type> struct mem_func_internal;
template<typename T, typename Ret> struct mem_func_internal<T, Ret (T::*)()> {
typedef Ret(T::* functype)();
T* obj;
functype func;
Ret operator()() {
return obj->*func();
}
};
template<typename T, typename Ret, typename ArgType1> struct mem_func_internal<T, Ret (T::*)(ArgType1) {
typedef Ret(T::* functype)();
T* obj;
functype func;
Ret operator()(ArgType1 arg) {
return obj->*func(arg);
}
}
template<typename T, typename mem_func_type> struct mem_func : public mem_func_internal<T, mem_func_type> {
mem_func(T* object, mem_func_type mem_func)
: obj(object)
, func(mem_func) {}
};
template<typename T, typename mem_func_type> mem_func<T, mem_func_type> bind_mem_func(T* object, mem_func_type func) {
return mem_func<T, mem_func_type>(object, func);
}
// Usage
std::for_each(wheel.begin(), wheel.end(), bind_mem_func(this, &Car::put));
It's been a while since I wrote code like this, so it might be a little off. But that's the gist of it. So hard to write a usage example without just using a lambda.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With