fork download
  1. #include <functional>
  2. #include <vector>
  3. #include <iostream>
  4. #include <memory>
  5.  
  6. template < typename CB > struct event
  7. {
  8. std::vector< std::function<CB> > call_back ;
  9.  
  10. template < typename FN > event<CB>& operator+= ( FN fn )
  11. {
  12. call_back.emplace_back(fn) ;
  13. return *this ;
  14. }
  15.  
  16. };
  17.  
  18. struct test
  19. {
  20. const std::string& name() const { return name_ ; }
  21.  
  22. void name( const std::string& new_name )
  23. { name_ = new_name ; fire_name_changed() ; }
  24.  
  25. event< void( const test&, const std::string& ) > name_changed ;
  26.  
  27. template < typename FN, typename... ARGS > void subscribe( FN fn, ARGS&&... args )
  28. {
  29. using namespace std::placeholders ;
  30. name_changed.call_back.emplace_back( std::bind( fn, args..., _1, _2 ) ) ;
  31. }
  32.  
  33. private:
  34.  
  35. std::string name_ = "anonymous" ;
  36.  
  37. void fire_name_changed()
  38. { for( const auto& f : name_changed.call_back ) f( *this, name() ) ; }
  39. };
  40.  
  41. void a_function( const test& sender, const std::string& value )
  42. {
  43. std::cout << "a_function: -\n name of object at "
  44. << std::addressof(sender) << " changed to: '" << value << "'\n\n" ;
  45. }
  46.  
  47. void another_fun( const std::string& msg, const test& sender, const std::string& value )
  48. {
  49. std::cout << "another_fun: -\n msg: '" << msg
  50. << "'\n sender: " << std::addressof(sender)
  51. << "\n value: '" << value << "'\n\n" ;
  52. }
  53.  
  54. int main()
  55. {
  56. test t ;
  57. t.name_changed += []( const test& sender, const std::string& value )
  58. {
  59. std::cout << "lambda: -\n name of object at "
  60. << std::addressof(sender)
  61. << " changed to: '" << value << "'\n\n" ;
  62. } ;
  63.  
  64. t.name_changed += a_function ;
  65.  
  66. t.subscribe( another_fun, "**** name of object is changed! ****" ) ;
  67.  
  68. struct recvr
  69. {
  70. void handle_it( const test& sender, const std::string& value ) const
  71. {
  72. std::cout << "recvr::handle_it -\n name of object at "
  73. << std::addressof(sender)
  74. << " changed to: '" << value << "'\n\n" ;
  75. }
  76. };
  77.  
  78. recvr r ;
  79. t.subscribe( &recvr::handle_it, r ) ;
  80.  
  81. t.name( "Cambalinho" ) ; // change the name to test it
  82. }
  83.  
Success #stdin #stdout 0s 3480KB
stdin
Standard input is empty
stdout
lambda: -
    name of object at 0xbfb05f70  changed to: 'Cambalinho'

a_function: -
    name of object at 0xbfb05f70  changed to: 'Cambalinho'

another_fun: -
    msg: '**** name of object is changed! ****'
    sender: 0xbfb05f70
    value: 'Cambalinho'

recvr::handle_it -
    name of object at 0xbfb05f70  changed to: 'Cambalinho'