C ++ 11 std :: bind работает странно

Это менеджер событий, принцип работы которого показан в 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;


В чем дело? Где ошибка?

Постскриптум я делаю new std::function<void()>; просто чтобы попытаться устранить ошибку …

Visual Studio 2013 (12.0.30 ..)

0

Решение

Вы вызываете 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;
}

что приводит к вызову второй сохраненной функции дважды, а первой сохраненной функции — ноль раз.

2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector