我已经编写了一个利用std::function
的简单订阅者事件系统。它很棒! (我可以在以后使用线程池进行昂贵的回调来进行一些大的改进)
改善这一点的下一步是处理具有多个参数的事件/回调。
除了在回调参数中强制struct
s / class
es或使用std::tuple
之外(我希望保持函数清洁或使用现有的简单函数)。有没有一种好方法可以做到这一点,并且有多个模板参数都使用相同的代码?
#pragma once
#include <mutex>
#include <vector>
template<typename PARAM>
class SoyEvent
{
public:
typedef std::function<void(PARAM&)> FUNCTION;
public:
// helper for member functions
template<class CLASS>
void AddListener(CLASS& This,void(CLASS::*Member)(PARAM&))
{
// http://stackoverflow.com/a/7582576
auto bound = std::bind( Member, &This, std::placeholders::_1 );
AddListener( bound );
}
template<class CLASS>
void RemoveListener(CLASS& This,FUNCTION Member)
{
RemoveListener( std::bind( &Member, &This ) );
}
// add static or lambda
void AddListener(FUNCTION Function)
{
std::lock_guard<std::mutex> lock(mListenerLock);
mListeners.push_back(Function);
}
void RemoveListener(FUNCTION Function)
{
std::lock_guard<std::mutex> lock(mListenerLock);
mListeners.erase(Function);
}
void OnTriggered(PARAM& Param)
{
std::lock_guard<std::mutex> lock(mListenerLock);
// todo: execute on seperate threads with a scheduler which can just execute std::functions
for ( auto it=mListeners.begin(); it!=mListeners.end(); it++ )
{
auto& Function = *it;
Function( Param );
}
}
private:
std::mutex mListenerLock;
std::vector<FUNCTION> mListeners;
};
答案 0 :(得分:3)
为什么不使用可变参数模板,即更改类定义:
template <typename PARAM>
class SoyEvent {
// Implementation
};
类似于:
template <typename... PARAMS>
class SoyEvent {
// Implementation
};
然后将FUNCTION
typedef更改为:
typedef std::function<void(PARAMS&...)> FUNCTION;
通常会将PARAM&
的所有实例更改为PARAMS&...
。