Passing a member function to for_each in C++03 (no boost, no c++11)

巧了我就是萌 提交于 2019-12-07 06:04:24

问题


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;
}

回答1:


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.




回答2:


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




回答3:


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.



来源:https://stackoverflow.com/questions/4642497/passing-a-member-function-to-for-each-in-c03-no-boost-no-c11

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!