C ++ 11:存储指向模板化类成员函数的指针

时间:2017-11-29 18:28:54

标签: c++11 templates pointers

我正在尝试在C ++ 11中实现通用的模板化观察者模式。目标是为任何类成员函数提供一种机制,使其能够注册为对观察者的回调。观察者模板如下:

template <typename... Args>
class tsubject {
public:

   /// @brief Register a member function of any class as callback to the subject.
   template <typename AnyObserver>
   void register( AnyObserver* observer, void(AnyObserver::*func)(Args... ) ) {
       register( [=]( Args... args ) {
           ( observer->*func )( args... );
       });
   }

   /// @brief Register an std::function as callback to the subject.
   void register( std::function<void(Args...)> const & func ) {
       mCallbacks.push_back( func );
   }

   /// @brief Notify all registered observers
   void update( Args... p ) {
       for( auto it : mCallbacks ) {
           it( p... );
       }
   }

private:
    std::vector<std::function<void(Args...)> mCallbacks;
};

用法:

class MyObserverClass {
public:
    void callback( std::string arg1, int arg2 ) {
       std::count << "callback:" << arg1 << ":" << arg2 << std::endl;
    }
}

int main( ) {
    tsubject<std::string, int> subject;

    MyObserverClass observer;
    subject.register( &observer, &MyObserverClass::callback );

    subject.update( "test", 1 );
}

输出:

callback: test:1

问题:

int main( ) {
    tsubject<std::string, int> subject;

    MyObserverClass observer;
    subject.register( &observer, &MyObserverClass::callback );
    subject.register( &observer, &MyObserverClass::callback );

    subject.update( "test", 1 );
}

输出:

callback: test:1
callback: test:1

此实现的问题在于,如果多次注册相同的观察者方法,则会多次触发回调。由于C ++ 11指向成员函数的指针不是普通指针,因此无法将它们类型转换为void *以供以后比较,因为这是一个可变参数模板函数,所以std :: map不能用于mCallback,因为该类型不能指定。是否有任何机制可以避免多次注册?

0 个答案:

没有答案