私はブースト ライブラリを使用しています。私の質問は、boost::signals に関するものです。
多くの異なるスロットを呼び出す可能性のあるシグナルがありますが、1 つのスロットのみが呼び出しに一致するため、この特定のスロットが true を返し、呼び出しが停止するようにします。
出来ますか?
効率的ですか?
効率的でない場合、より良い方法を提案できますか?
3 に答える
いくつかの調査の後、ブーストのドキュメントで、値を返すスロットについて書いていることがわかりました。
彼らは、次のような別のコンバイナーを使用することを提案しています。
struct breakIfTrue
{
template<typename InputIterator>
bool operator()(InputIterator first, InputIterator last) const
{
if (first == last)
return false;
while (first != last) {
if (*first)
return true;
++first;
}
}
};
boost::signal<bool(), breakIfTrue> sig;
では、なぜそれが間違っているのでしょうか。
可能かもしれませんが、シグナルとスロットの「一般的なパブリッシュ/サブスクライブ」の意図に反していることは確かです。
あなたが本当に求めているのは、Chain of Responsibility のデザイン パターンだと思います。
ドリューが言うように、これはシグナルとスロットにふさわしくないように思えます。
そして、dribeas が言うように、回避策は、最初にbool& found
false で始まるパラメーターを持つプロトコルであり、すべてのスロットが最初にチェックし、true の場合は戻ります。いずれかのスロットが値を true に設定すると、他の呼び出しの処理が非常に迅速に行われます。
しかし、すべてのベース (お勧めできないものも含む) をカバーするために、boost:: シグナルはすべて呼び出し元と同じスレッドで実行されるため、シグナル内からカスタム例外をスローし、それをキャッチすることができることに言及します。呼び出しサイト。良くも悪くも、ブースト グラフ ライブラリのビジター アルゴリズムのように、他に選択肢がないと感じたときに、これに頼ることがあります。
カスタム ビジターを使用しているときに、Boost Graph Library を使用して幅優先検索を停止するにはどうすればよいですか?
そして、私がそれについて言及したので、そのようにしないでください. :)
更新:知りませんでしたが、boost には、結果の値ではなくイテレータを受け取るコンバイナを使用して、これをエレガントに処理するメカニズムがあることがわかりました。
「コンバイナに渡された入力イテレータは、逆参照操作をスロット呼び出しに変換します。したがって、コンバイナには、特定の基準が満たされるまで、一部のスロットのみを呼び出すオプションがあります。」
ブーストに固執していると確信している場合は、自分の質問に答えたことになります。ただし、他のシグナル/スロットシステム (Qt など) にはこれと同等のものがないことに注意してください...