質問は厳密に約std::function
であり、boost::function
ではありません。詳細については、この質問の最後にあるアップデートのセクションを参照してください。特に、C++ 11標準で空でないstd::function
オブジェクトを比較することはできません。std :: functionがコールバックとして登録解除可能ですか?
C++ 11 std::function
クラステンプレートは、コールバックのコレクションを維持するのに最適です。たとえば、それらをvector
に格納し、必要に応じて呼び出すことができます。しかし、これらのオブジェクトを維持し、登録解除を許可することは不可能であるようです。
は、このクラスを想像し、私は具体的にしてみましょう:
class Invoker
{
public:
void Register(std::function<void()> f);
void Unregister(std::function<void()> f);
void InvokeAll();
private:
// Some container that holds the function objects passed to Register()
};
サンプル使用シナリオ:
void foo()
{
}
int main()
{
std::function<void()> f1{foo};
std::function<void()> f2{[] {std::cout << "Hello\n";} };
Invoker inv;
// The easy part
// Register callbacks
inv.Register(f1);
inv.Register(f2);
// Invoke them
inv.InvokeAll();
// The seemingly impossible part. How can Unregister() be implemented to actually
// locate the correct object to unregister (i.e., remove from its container)?
inv.Unregister(f2);
inv.Unregister(f1);
}
Register()
機能を実現することができるか、かなり明白です。しかし、どうすればUnregister()
を実装するのでしょうか。関数オブジェクトを保持するコンテナがvector<std::function<void()>>
であるとします。 Unregister()
呼び出しに渡される特定の関数オブジェクトをどのように見つけることができますか? std::function
は、オーバーロードされたoperator==
を提供しますが、空の関数オブジェクト(つまり、2つの空ではない関数オブジェクトを比較して、両方が同じ実際の呼び出しを参照しているかどうかを確認することはできません)
私は何か考えていただければ幸いです。
更新:
アイデアこれまで主に、それを登録解除するために使用することができ、各std::function
オブジェクトに関連付けられるクッキーの添加から成ります。私はstd::function
オブジェクト自体に外生的ではない何かを望んでいました。また、std::function
とboost::function
の間に多くの混乱があるようです。問題は厳密に約std::function
オブジェクトであり、ではなく、boost::function
オブジェクトです。
また、空でない2つのstd::function
オブジェクトを比較することはできません。彼らは常に、標準に準拠していないものと比較します。ですから、この問題の文脈では、コメントだけでそれを行うソリューション(そしてboost::function
オブジェクトを起動する)へのリンクが間違っています。
接続ポイントでMSが行ったことを実行できます。発信者が登録抹消に提供するCookie(ベクトルへのインデックス)を返します。 – WhozCraig
私はしばしばコールバックとしてインターフェイスポインタを格納し、それをセットに入れます。それから私は値でアクセスして登録を解除することができます。 –
@RogerRowlandいいアイデア。 – WhozCraig