最近、私はboost::signal
を隠す柔軟なオブザーバパターンの実装を作成しようとしていました。私はほぼ成功した。テンプレートシグネチャからboost :: functionを作成する方法
私は、Observer
クラスを持っています。これは、テンプレートパラメータによって提供されるupdate
メソッドシグネチャと一致するメソッドを持つ必要があります。使用の
例: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);
すべてがうまく動作します。この場合、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
は、この問題を解決するのに役立つことができると思います。テンプレートの署名だけを使って正しいメンバメソッドとバインドする方法がわかりません。
それは可能ですか?
ありがとうございます。あなたのソリューションは美しく動作します。 :) – Wojciech