
Le 12/05/15 04:25, Emil Dotchevski a écrit :
Hello,
I realize that Boost has Signals library already, but I've implemented a non-intrusive one which approaches the problem differently, and I'm pretty sure that there is no overlap between the two. It turned out more generic than I originally anticipated, so I thought I'd ask if others would find it useful as well.
I have some concerns about the lifetime of the emitters. E.g. an application can have a class that contains a several possible emitters. The lifetime of all the emitters depends on the lifetime of the C instance. struct C { T1 e1; T2 e2; }; int main() { shared_ptr<C> c = make_shared<C>(); // ... The lifetime of emitters c->e1 and c->e2 is managed by c. Now I would like to connect to c->e1 and/or c->e2. But I would need to change the class C, as I don't have a shared_ptr to &(c->e1) or &(c->e2). Do you have a solution without changing C? If not, could your library take care of this use case? IMO this will reduce the need for more shared_ptr than really needed. Maybe a connect_member auto c1 = connect_member<button_clicked, C, T1, &C::e1>(c , ...); auto c2 = connect_member<button_clicked, C, T2, &C::e2>(c, ...); or splitting the responsabilities of emitter lifetime tracker and the emitter itself auto c1 = connect<button_clicked>(c, c->e1, ...); auto c2 = connect<button_clicked>(c, c->e2, ...); Maybe having a smart pointer that give access to a member pointer of a shared_ptr/weak_ptr template <class C, class T, T C::*> class member_shared_ptr; template <class C, class T, T C::*> class member_weak_ptr; could allow to overload the connect function auto c1 = connect<button_clicked>(member_shared_ptr<C, T1, &C::e1>(c), ...); auto c2 = connect<button_clicked>(member_shared_ptr<C, T2, &C::e2>(c), ...); The class C could be defined as follows to make explicit that the instances are shared and provide access to shared emitters struct C : shared_from_this { T1 e1_; T2 e2_; public: shared_ptr<C> make(); member_shared_ptr<C, T1, &C::e1> e1_emitter() { return member_shared_ptr<C, T1, &C::e1>(share_from_this()); } member_shared_ptr<C, T2, &C::e2> e2_emitter(){ return member_shared_ptr<C, T2, &C::e2>(share_from_this()); } }; auto c = C::make(); auto c1 = connect<button_clicked>(c->e1_emitter(), ...); auto c2 = connect<button_clicked>(c->e2_emitter(), ...); Vicente