2010-09-14 3 views
1

У меня есть список Thing и Controller, что я хочу notify() с каждой из вещей. Приведенный ниже код работает:Вызывать функцию члена C++ с каждым элементом в списке?

#include <algorithm> 
#include <iostream> 
#include <tr1/functional> 
#include <list> 
using namespace std; 

class Thing { public: int x; }; 

class Controller 
{ 
public: 
    void notify(Thing& t) { cerr << t.x << endl; } 
}; 

class Notifier 
{ 
public: 
    Notifier(Controller* c) { _c = c; } 
    void operator()(Thing& t) { _c->notify(t); } 
private: 
    Controller* _c; 
}; 

int main() 
{ 
    list<Thing> things; 
    Controller c; 

    // ... add some things ... 
    Thing t; 
    t.x = 1; things.push_back(t); 
    t.x = 2; things.push_back(t); 
    t.x = 3; things.push_back(t); 

    // This doesn't work: 
    //for_each(things.begin(), things.end(), 
    //   tr1::mem_fn(&Controller::notify)); 

    for_each(things.begin(), things.end(), Notifier(&c)); 
    return 0; 
} 

Мой вопрос: могу ли я избавиться от Notifier класса, используя некоторую версию «Это не работает» линия? Похоже, я должен что-то сделать, но не могу получить правильную комбинацию. (Я возился с рядом различных комбинаций.)

Без использования boost? (Я бы мог, если бы мог.) Я использую g ++ 4.1.2, да, я знаю, что он старый ...

ответ

4

Вы можете выполнить это, используя bind, который первоначально был из Boost, но включен в TR1 и C + + 0x:

using std::tr1::placeholders::_1; 
std::for_each(things.begin(), things.end(), 
       std::tr1::bind(&Controller::notify, c, _1)); 
+0

Спасибо Джеймс, это именно то, что я искал. – bstpierre

3

насчет идущей старой школы:

for(list<Thing>::iterator i = things.begin(); i != things.end(); i++) 
    c.notify(*i); 
+1

Потому что это слишком очевидно? :) Честно говоря, это для обучения, я пытаюсь понять, как это делается в новой школе. – bstpierre

Смежные вопросы