Как сделать функтор из функции-члена? - PullRequest
2 голосов
/ 13 февраля 2011

Я хочу run позвонить c.drive():

#include <functional>
using namespace std;

struct Car {
    void drive() { }
};

template <typename Function>
void run(Function f) {
    f();
}

int main() {
    Car c;    
    run(bind1st(mem_fun(&Car::drive), &c));    
    return 0;
}

Это не компилируется и сообщения об ошибках мне не помогают:

при f ():
нет совпадения для вызова '(std :: binder1st>) () '

при вызове для запуска:
нет типа с именем' first_argument_type 'в' классе std :: mem_fun_t'
нет типа с именем' second_argument_type 'в' классе std :: mem_fun_t'

Не буст, пожалуйста.

Обновление: , даже если проблема решена, я был бы очень рад увидеть TR1 / C ++0x решений!

Ответы [ 3 ]

9 голосов
/ 13 февраля 2011

Решение Boost / TR1 / C ++ 0x довольно простое:

run(std::bind(&Car::drive, &c));
7 голосов
/ 13 февраля 2011

bind1st делает унарную функцию из двоичной функции и значения.Вы пытаетесь создать функцию, которая не принимает параметры из унарной функции, и в стандарте C ++ 03 нет ничего, что поддерживало бы это.

Вам придется сделать что-то подобное.

template<class X, void (X::*p)()>
class MyFunctor
{
    X& _x;
public:
    MyFunctor(X& x) : _x( x ) {}
    void operator()() const { (_x.*p)(); }
};

template <typename Function>
void run(Function f) {
    f();
}

int main() {
    Car c;
    run(MyFunctor<Car, &Car::drive>(c));
    return 0;
}
6 голосов
/ 13 февраля 2011

Решение C ++ 0x с использованием лямбда-выражений - http://www.ideone.com/jz5B1:

struct Car {
    void drive() { }
};

template <typename Function>
void run(Function f) {
    f();
}

int main() {
    Car c;    
    run( [&c](){ c.drive(); } );    
    return 0;
}
...