2009-02-23 6 views
0

Не удалось творчески сократить название :)Как передать, а затем вызвать общие функции обратного вызова, не вызывая циклическую зависимость

Я использую вариацию ниже решения, однако я всегда задавался вопросом, есть ли лучше/более чистый способ его реализации. Я ищу небуксовое решение. Тем не менее, мы можем взглянуть на реализацию boost и C++ 0x, поскольку это скоро будет актуальным.

//Notice the use of template template parameter 
template <template <typename> class Callback> 
class A { 
    Callback <A> m_func; 
    public: 
    A (Callback <A> func): m_func (func) {} 
    void call() { m_func(*this);} 

}; 

template <typename T> 
struct MYCallback 
{ 
    void operator() (const T&t) {} 

}; 


void Test() 
{ 
    typedef A<MYCallback> AType; 

    MYCallback<AType> callback; 
    AType a (callback); 
    a.call(); 

} 

Другой, более suncinct способом, является использование tr1 :: функцию, которая станет defuct к новой стандартизации:

#include <tr1/functional> 


class A { 
    std::tr1::function <void (const A&)> m_func; 
    public: 
    template <class Callback> 
    A (Callback func) : m_func (func) {} 

    void call() { m_func(*this);} 

}; 

template <class T> 
struct My_callback 
{ 
    void operator() (const T&t) {} 

}; 

void Test() 
{ 
    My_callback <A> c; 
    A a (c); 
    a.call(); 
} 
+0

Простите, я не совсем понимаю смысл вашего кода. Почему бы не увеличить :: bind и boost :: function делать то, что вы хотите? Это кажется смехотворным сложным - я должен упустить что-то мощное, что это позволяет вам делать. –

+0

Я понятия не имею, каков ваш реальный вопрос. можете ли вы перефразировать то, что вы хотите достичь? –

ответ

0

Если вы просто ищете советы по очистке, я бы предложил сделать «My_callback» обычным классом, а не шаблоном класса. В этом случае нет очевидной необходимости, чтобы это был шаблон. Вместо этого, сделать его применить оператор шаблонным или заполнить непосредственно, если My_callback только имеет дело с экземплярами:

#include <tr1/functional> 

class A { 
    std::tr1::function <void (const A&)> m_func; 
    public: 
    template <class Callback> 
    A (Callback func) : m_func (func) {} 

    void call() { m_func(*this);} 

}; 

struct My_callback 
{ 
    template <class T> 
    void operator() (const T&t) {} 
}; 

int main() 
{ 
    My_callback c; 
    A a (c); 
    a.call(); 
} 

В противном случае, это выглядит довольно хорошо, как есть. Не могли бы вы уточнить, как вы надеетесь очистить его или упростить?

1

Я всегда считаю, что пустота * является вашим другом, когда вы хотите элегантности в этих вещах.

+0

Просьба привести пример использования рекурсии с обратными вызовами во избежание зависимостей? благодаря – 2009-02-23 17:06:29

0

Один из способов сделать это является с производным классом:

template <class Callback> 
class A { 
    Callback m_func; 
    public: 
    A (Callback func): m_func (func){} 
    void call() { m_func(*this);} 

}; 

template <typename T> 
struct MYCallback 
{ 
    void operator() (const T&t) {} 

}; 


struct AConcrete : public A<MYCallback<AConcrete> > 
{ 
    template <class T> 
    AConcrete(T t): A<MYCallback<AConcrete> > (t) {} 
}; 

void Test() 
{ 

    MYCallback<AConcrete> callback; 
    AConcrete a (callback); 
    a.call(); 

} 

PS: Рекурсия жесток с шаблонами C++.