?????????????????????????????C++?????????????????????????????????????????????ú?????VC11????????XP????????????????C++11????????????????????????ɡ?

????????????????????????Щ?????

????1????????ж???????????????????std::function??????????????????function??????????????

????2?????????????????????????????????????????????

????3???????з???????????????????????????????????????????????緵?????д??????е??С????????????????????????????????

????4????????????????????????????????????0~10????????VC11?????????????????GCC????????????????????????????????????????????????????

????5?????????????

???????3??5??????????????????????????????????????Loki??????????????????????????????

???????????

#include <map>
 #include <functional>
 
 using namespace std;
 
 
 template<class Param1?? class Param2>
 class Event
 {
     typedef void HandlerT(Param1?? Param2);
     int m_handlerId;
 
 public:
     Event() : m_handlerId(0) {}
 
     template<class FuncT> int addHandler(FuncT func)
     {
         m_handlers.emplace(m_handlerId?? forward<FuncT>(func));
         return m_handlerId++;
     }
 
     void removeHandler(int handlerId)
     {
         m_handlers.erase(handlerId);
     }
 
     void operator ()(Param1 arg1?? Param2 arg2)
     {
         for ( const auto& i : m_handlers )
             i.second(arg1?? arg2);
     }
 
 private:
     map<int?? function<HandlerT>> m_handlers;
 };

????addHandler?????????????????std::function?????????????????????????????????????????????????£???????????

void f1(int?? int)
 {
     puts("f1()");
 }
 
 struct F2
 {
     void f(int?? int)
     {
         puts("f2()");
     }
 
     void operator ()(int?? int)
     {
         puts("f3()");
     }
 };
 
 int _tmain(int argc?? _TCHAR* argv[])
 {
     Event<int?? int> e;
 
     int id = e.addHandler(f1);
 
     e.removeHandler(id);
 
     using namespace std::placeholders;
 
     F2 f2;
 
     e.addHandler(bind(&F2::f?? f2?? _1?? _2));
     e.addHandler(bind(f2?? _1?? _2));
 
     e.addHandler([](int?? int) {
         puts("f4()");
     });
 
     e(1?? 2);
 
     return 0;
 }