Search code examples
c#c++c++11lambdaaction

C++ way of C# Action += function?


in C# we can say:

Action act = ()=> {/*stuff*/}; 
act += ()=> {/*another stuff*/}` 

and then call act().

I wonder how to do such thing in C++ (now with lambdas it will be quite usefull and if possible not using Boost/Qt signals)?


Solution

  • You can write something like this rather easily, by filling a std::vector<std::function<void()>> with the lambdas and invoke every function object.

    #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
    

    However, from what I know, C# also allows you to remove a handler with -=, which isn't as easy to accomplish in C++. You'd need to return a token from += which can be passed to -= to remove that specific handler.