C# では次のように言えます。
Action act = ()=> {/*stuff*/};
act += ()=> {/*another stuff*/}`
を呼び出しますact()
。
C ++でそのようなことを行う方法を知りたいです(ラムダを使用すると非常に便利になり、可能であればBoost/Qt信号を使用しないでください)?
たぶんstd::function
s:
std::vector<std::function<void()>> act;
act.emplace_back([] { /* stuff */ });
act.emplace_back([] { /* more stuff */ });
呼び出すには:
for (auto & f : act) { f(); }
std::vector<std::function<void()>>
aをラムダで埋め、すべての関数オブジェクトを呼び出すことで、このようなものをかなり簡単に書くことができます。
#include <vector>
#include <functional>
#include <utility>
// warning: very crude and likely with typos / bugs
template<class Sig>
struct Action{
template<typename Functor>
void operator+=(Functor&& f)
{ _funcs.emplace_back(std::forward<Functor>(f)); }
template<class... Args>
void operator()(Args&&... args) const{
for(auto& f : _funcs)
f(args...);
}
private:
std::vector<std::function<Sig>> _funcs;
};
// ...
Action<void()> act;
act += []{ /*...*/ };
act += []{ /*...*/ };
act(); // invoke all handlers in order
ただし、私の知る限り、C# では を使用してハンドラーを削除-=
することもできますが、これは C++ では簡単に実現できません。その特定のハンドラーを削除するに+=
は、渡すことができるトークンを返す必要があります。-=