1

having some observable class, the way I naively use signals2 is to provide a member signal so that anybody can connect

struct Observable {
  boost::signals2::signal<void(Observable const *)> aSignal;
  void foo() {
    //something happens
    aSignal(this);
  }
};

For a better encapsulation, maybe adding some public subscribe and hide aSignal to avoid external classes to invoke the signal.

Now, the thing is that boost::signals2::signal::connect method is non-const which is understandable since the list of connections is modified. However, this prevents using signals for just-observing classes, which just want to react to the modification of the Observable without modifying it.

struct Observer {
  //here I need to pass a non-const Observable
  Observer(Observable * observed) : connection(observed.aSignal.connect(std::bind(this,&Observer::react) {}
  void react(Observable const *) {
    //do something to const Observable
  }
  boost::signals2::scoped_connection connection;
};

A way to get around the problem is to make mutable those signals that send const this and const subscribe functions.

struct Observable {
  void foo() {
    //something happens
    aSignal(this);
  }
  template<typename aFoo>
  boost::signals2::connection subscribe(aFoo && foo) const {
    return aSignal.connect(std::forward<aFoo>(foo));
  }
  private:
  mutable boost::signals2::signal<void(Observable const *)> aSignal;
};

Is that an anti-pattern?

Another way around is maybe using an intermediate proxy class that allows connecting to const and to non-const Observable, but then I would lose any advantage of having signals already coocked for me.

Or I just have to give up const-correctness?

Or there is something that I am missing?

Teloze
  • 279
  • 2
  • 8

0 Answers0