最近、私はを隠す柔軟なオブザーバーパターンの実装を作成しようとしていましたboost::signal
。私はほとんど成功しました。
テンプレートパラメータによって提供される署名に一致するメソッドを持たなければならないObserver
クラスがあります。update
使用例:
Observable<void(float, float)> observable;
Observer<void(float, float)> observer;
observable.attach(&observer);
observable.notify(Observable::Arguments(10.0f, 1.0f)); // invokes observer->update(10.0f, 1.0f);
オーバーロードされたメソッドobserver
がない場合は、すべてが正常に機能します。update
その場合boost::bind
、使用する正しい方法を推測することはできません。残念ながら、更新引数がわからないため、明示的なキャストを使用できません(この情報はにありFunctionSignature
ます)。
次の方法で問題が発生します。
class Observable <typename FunctionSignature>
{
...
template <class DerivedObserverClass>
void attach(DerivedObserverClass* observer)
{
STATIC_ASSERT((boost::is_base_of<ObserverType, DerivedObserverClass>::value));
ConnectionsMap::iterator it = connections.find(observer);
if (it == connections.end() || !it->second.connected()) {
// i would like to do something like
// boost::function<FunctionSignature> f;
// f = boost::bind(&static_cast<FunctionSignature>DerivedObserverClass::update, observer, _1);
// singnalSlot is defined as boost::signal<FunctionSignature>
// this works as long, as Derived class doesn't have overloaded update method
connections[observer] = signalSlot.connect(boost::bind(&DerivedClass::update, observer, _1));
} else {
throw std::invalid_argument("Observer already attached.");
}
}
boost::function
それがこの問題の解決に役立つと思います。テンプレートの署名のみを使用して、正しいメンバーメソッドでバインドする方法がわかりません。
それも可能ですか?