質問は厳密には についてstd::function
であり、 ではありませんboost::function
。詳細については、この質問の下部にある更新std::function
セクションを参照してください。特に、C++ 11 標準に従って空でないオブジェクトを比較できないことに関する部分です。
C++11std::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
はオーバーロードされた を提供しますが、それは空の関数オブジェクトをテストするだけです (つまり、2 つの空でない関数オブジェクトを比較して、両方が同じ実際の呼び出しoperator==
を参照しているかどうかを確認するために使用することはできません)。
アイデアをいただければ幸いです。
アップデート:
std::function
これまでのアイデアは、主に、オブジェクトの登録を解除するために使用できる各オブジェクトに関連付けられる Cookie の追加で構成されています。std::function
オブジェクト自体に外生的ではない何かを望んでいました。std::function
また、 と の間には多くの混乱があるようboost::function
です。問題は厳密にはオブジェクトに関するstd::function
ものであり、オブジェクトではありません boost::function
。
また、2 つの空でないstd::function
オブジェクトが等しいかどうかを比較することはできません。それらは常に標準に従って等しくないものを比較します。したがって、この質問のコンテキストでは、コメント内のそれを行う (そしてboost::function
オブジェクトを使用して起動する) ソリューションへのリンクは明らかに間違っています。