더 깨끗하고 사용하기 쉬운 인터페이스를 얻기 위해 boost::signals2::signal
에 대한 래퍼를 작성하고 있습니다.신호 콜백을 전달하는 방법 (boost :: bind 사용)
#include <boost/signals2.hpp>
// Wrapper class template for boost::signals2::signal
template<typename T>
class Signal {
typedef typename boost::signals2::signal<T> SignalType;
public:
// Trigger the signal
void operator()() { sig(); }
// Attach a listener
boost::signals2::connection operator+=(const typename SignalType::slot_type& slot)
{ return sig.connect(slot); }
private:
SignalType sig;
};
class ClassThatGeneratesEvents {
public:
void generateEvents(int n) {
while (n-- > 0) {
SomethingHappened();
}
}
Signal<void()> SomethingHappened;
};
void func()
{
;
}
class ClassThatListensForEvents {
public:
ClassThatListensForEvents(ClassThatGeneratesEvents& ev) {
received_count = 0;
// This works
ev.SomethingHappened += func;
// This doesn't!
ev.SomethingHappened += bind(&ClassThatListensForEvents::event_handler, this, _1);
}
void event_handler() {
received_count++;
}
int received_count;
};
나는 이것이 내가 가지고 올 수있는 최고의 래퍼 인터페이스입니다 확실하지 않다, 그리고 결정은 public 멤버 아마도 몇 가지 단점이있을 수 있습니다 SomethingHappened : 내가 가지고 올 한 내용을 여기입니다. 그것에 대해 당신의 의견을 듣는 것을 꺼리지는 않지만, 이것이 문제가되는 것이 아닙니다.
궁금한 점은 +=
연산자에 콜백을 전달하는 방법입니다. ClassThatListensForEvents
으로 작성 했으므로 함수에 대한 콜백은 문제가되지 않지만 결과로 bind
을 사용하면 읽기 어려운 템플릿 컴파일러 오류가 많이 발생합니다.
당신이 그런 랩퍼를 작성하기 전에, 그것은 [디자인하여 Rational (읽을 가치가 http://www.boost.org/doc/libs/ 1_53_0/doc/html/signals/s06.html # idp161393904) 섹션을 참조하십시오. –
나는 그것을 한 번 읽었으며 Boost의 일반적인 맥락에서 그것에 동의하지만, 응용 프로그램의 맥락에서 나는 결정할 사람이다. 나는 그 깨끗한 인터페이스를 좋아한다. 단점은 나에게 커다란 관심사가 아니다. 그곳에. 그러나'+ ='는 단지 설탕 일 뿐이므로 래퍼 작성의 진정한 이유는 클래스의 사용자로부터'boost :: signals2 :: signal' 클래스를 숨겨 복잡성을 줄이고 앞으로 다른 구현을 허용하는 것입니다. – Jonatan