它是事件管理器,其工作原理显示在main()中。 所以,代码:
class CEventManager
{
public:
static CEventManager *const GetInstance()
{
static CEventManager pInstance;
return &pInstance;
};
template <typename... ARGS>
bool RegCallback(E_EVSYS_MSG const &_eType, void (*_Func)(ARGS...))
{
m_Callbacks[_eType].push_back(_Func);
return true;
};
template <typename... ARGS>
bool CallEvent(E_EVSYS_MSG const &_eType, ARGS... _Args)
{
auto const &FuncsVector = m_Callbacks[_eType];
for (auto const _Func : FuncsVector)
{
typedef void(*FUNC)(ARGS...);
FUNC StoredFunc = (FUNC)_Func;
std::function<void()> *pBindFunc = new std::function<void()>;
*pBindFunc = std::bind(StoredFunc, _Args...);
m_Queue.push(pBindFunc);
}
return true;
};
bool Exec()
{
while (!m_Queue.empty())
{
std::function<void()> *iFunc = new std::function<void()>;
*iFunc = *m_Queue.back();
(*iFunc)();
m_Queue.pop();
}
return true;
};
private:
std::unordered_map<E_EVSYS_MSG, std::vector<void *>> m_Callbacks;
std::queue<std::function<void()> *> m_Queue;
};
void SomeCallback(int n, float f)
{
printf("void SomeCallback(int, float): %d %0.1f\n", n, f);
}
int main()
{
CEventManager::GetInstance()->RegCallback(E_EVSYS_MSG::MATHSQRT, &SomeCallback);
CEventManager::GetInstance()->CallEvent(E_EVSYS_MSG::MATHSQRT, 10, 10600.0f);
CEventManager::GetInstance()->CallEvent(E_EVSYS_MSG::MATHSQRT, 12, 1.0f);
CEventManager::GetInstance()->Exec();
return 0;
}
输出是:
void SomeCallback(int,float):12 1.0
void SomeCallback(int,float):12 1.0
如果我换行:
CEventManager::GetInstance()->CallEvent(E_EVSYS_MSG::MATHSQRT, 12, 1.0f);
CEventManager::GetInstance()->CallEvent(E_EVSYS_MSG::MATHSQRT, 10, 10600.0f);
输出变成这样:
void SomeCallback(int,float):10 10600.0
void SomeCallback(int,float):10 10600.0
调试器显示,在m_Queue中,所有数据都是正确的。
这意味着,队列数据中的数据是这样的:
首先: func:void(int,float);参数:12,1.0f;
第二名: func:void(int,float);参数:10,10600.0f;
怎么了?哪里出错?
P.S。我new std::function<void()>;
只是试图解决这个错误......
Visual Studio 2013(12.0.30 ..)
答案 0 :(得分:2)
您正在m_Queue.back()
而不是Exec
中调用m_Queue.front()
:
bool Exec()
{
while (!m_Queue.empty())
{
std::function<void()> *iFunc = new std::function<void()>;
*iFunc = *m_Queue.back();
(*iFunc)();
m_Queue.pop();
}
return true;
}
导致第二次存储函数调用两次,第一次存储函数调零次。