I find Observer pattern a very useful tool to decrease coupling between modules of a system. Boost provides Signals2 which can be used for that purpose. But adding Signal2 objects to arbitrary classes is not very convenient, because your must manually implement RegisterEvent/FireEvent functions.

What I was looking for is a reusable mixin which could add “Observable” behavior to arbitrary class with minimal hassle. Ideally, the user of mixing must only provide event table which contains event tags and handler signatures, e.g. (in pseudocode):

EventTable {
  EventA: void(),
  EventB: int(bool),
  ...
}

I came up with working proof of concept which uses CRTP-based mixin and traits class for event table declaration. I'm new to template meta-programming, so I'm looking forward to comments about possible improvements.

In particular, I'm not very satisfied with syntax boost::fusion::pair<Show, boost::optional<boost::signals2::signal<void()>>> (see attachement). I think, I can do better by allowing user to specify just boost::fusion::pair<Show, void()> and then generate proper type with mpl::transform and/or fusion::transform. This way is shorter and implementation details (optional, signals2) are hidden from the user.

The mixin code (full code with example usage in attachment):

#include <utility>

#include <boost/fusion/container/map.hpp>
#include <boost/fusion/sequence/intrinsic/at_key.hpp>
#include <boost/fusion/sequence/intrinsic/value_at_key.hpp>
#include <boost/optional.hpp>
#include <boost/signals2.hpp>
#include <boost/utility/in_place_factory.hpp>

//*****************************************************************************
// EventSource mixin
//*****************************************************************************

// event source traits base (concrete event source must create specialization)
template<typename ConcreteEventSource> struct Events;

// event source mixin (using CRTP)
template<typename ConcreteEventSource> class EventSource {
public:
  typedef ::Events<ConcreteEventSource> Events;

private:
  typedef typename Events::EventTable EventTable;
 
  // helper type generator
  template<typename Event> struct GetType {
    // boost::optional type
    typedef typename boost::fusion::result_of::
    value_at_key<EventTable, Event>::type SignalWrapper;
    // boost::signal type for particular boost::optional type
    typedef typename SignalWrapper::value_type Signal;
    // slot return type for particular boost::signal type
    typedef typename Signal::result_type SignalReturnType;
  };

public:
  // connect event handler
  template<typename Event, typename Handler>
  void Connect(Handler&& handler) {
    GetSignal<Event>()->connect(std::move(handler));
  }

protected:
  // generate nullary signal
  template<typename Event>
  typename GetType<Event>::SignalReturnType FireEvent() {
    return GetSignal<Event>()->operator()();
  }
 
  // generate unary signal
  template<typename Event, typename Arg1>
  typename GetType<Event>::SignalReturnType FireEvent(Arg1 arg1) {
    return GetSignal<Event>()->operator()(arg1);
  }

  // ... more overloads (MSVC does not support variadic templates)

private:
  // creates signal if not exists, returns reference to it
  template<typename Event>
  typename GetType<Event>::SignalWrapper& GetSignal() {
    auto& signal = boost::fusion::at_key<Event>(signals_);
    if (!signal)
      signal = boost::in_place();
    return signal;
  }

  EventTable signals_;
};