boost :: bind & boost :: function указатели на перегруженные или шаблонные функции-члены - PullRequest
14 голосов
/ 16 декабря 2009

У меня есть механизм обратного вызова, участвуют следующие классы:

class App
{
    void onEvent(const MyEvent& event);
    void onEvent(const MyOtherEvent& event);

    Connector connect;
}

class Connector
{  
   template <class T> void Subscribe(boost::function <void (const T&)> callback);
}

App::App()
{
    connect.Subscribe<MyEvent>(&App::OnEvent<MyEvent>);
}

Во-первых, этот код не компилируется, это иллюстрация.

Использование шаблонов усложняет мой пример, но я оставил их, потому что это влияет на мою проблему. Мне кажется уверенным, что моя подписка должна быть шаблонной, потому что класс Connector не знает, сколько типов событий он обрабатывает. Когда я пытаюсь создать:

boost::function f = &App::OnEvent, 

Я пытался создать OnEvent как функцию шаблона со специализациями, но, похоже, компилятор рассматривает мои функции OnEvent как перегрузки, а не как специализации шаблона, иначе я получаю специализацию шаблона не из-за ошибки пространства имен, если пытаюсь явно объявить это как

template <> OnEvent(const MyEvent& e) ...

Я могу получить следующее для компиляции:

boost::function <void (App*, const MyEvent&)> f = &App::OnEvent;
f(this, e); 

Это компилирует, запускает и работает.

boost::function<void (const MyEvent&)> g = boost::bind(&App::OnEvent, this);

нет. Я думаю, потому что я не правильно указываю адрес перегруженной функции.

Теперь, объяснив все это плюшевому медведю - я думаю, что мой вопрос: «Как правильно создать указатель функции на перегруженную или шаблонную функцию-член и связать с ней указатель this?»

Ответы [ 2 ]

32 голосов
/ 16 декабря 2009

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

boost::bind( static_cast<void (App::*)( MyEvent& )>(&App::OnEvent) , this, _1);

Аналогичная проблема + решение на gamedev.net

4 голосов
/ 16 декабря 2009

Вы собираетесь хотеть сделать

boost::function<void (const MyEvent&)> g = boost::bind(&App::OnEvent, this, _1);

Вы должны быть в состоянии сделать г (событие); с этим

Я не совсем уверен, чего вы здесь добиваетесь, но сейчас это должно решить одну из ваших проблем.

...