Я работаю над классом менеджера ввода, основанным на шаблоне наблюдателя, используя std :: function и std :: bind.
Класс входного менеджера выводится из класса "Observable", который включает в себя метод "Register (...)":
std::map<Event, std::vector<std::function<void()>>> m_observers;
template <class Observer, class... Args>
void Register(Event&& event, Observer&& observer, Args&&... args)
{
m_observers[std::move(event)].push_back(std::bind(std::forward<Observer>(observer), std::forward<Args>(args)...));
}
Таким образом, вы можете регистрировать темы в менеджере ввода. Менеджер ввода, чем отправляет текущий вход (данный из ОС) всем его слушателям (темам). Для этого будет вызван зарегистрированный обратный вызов субъекта. Этот обратный вызов должен иметь произвольную подпись.
В тематическом классе я вызываю регистр при инициализации следующим образом:
GameApp::InputManager.Register(
InputType::Keyboard,
&IntroGameState::OnInput,
this,
//sf::Event()
std::placeholders::_1
);
Произошла следующая ошибка компилятора:
c:\program files (x86)\microsoft visual studio 12.0\vc\include\function (900): ошибка C2027: использование неопределенного типа 'std :: tuple_element <0, _Ftuple>'
Если передать действительный аргумент методу register (как args...), например, "sf :: Event()", все работает. Но в данный момент я только хотел бы зарегистрировать тему и сказать, какой вызов следует вызывать в случае, если менеджер ввода имеет некоторый ввод для объекта. Я хочу дать аргумент от менеджера ввода к теме. И не вице-верка. При регистрации субъекта субъекту я не знаю аргументов. Аргументы должны быть предоставлены от менеджера к предмету (через обратный вызов). Поэтому я думал, что местозаполнитель в регистровом коде (по теме) будет в порядке. Но это приводит к ошибке компилятора, как упоминалось выше.
Любые идеи, как я могу решить проблему?
Вы пытаетесь заполнить слот формы
std::function<void()>
с результатом вызова std::bind
с std::placeholders::_1
качестве одного из аргументов. Связывание предоставляет operator()
который принимает один аргумент, std::function
ожидает, что сможет вызвать его с помощью none. Вот почему это не компилируется.
Если я понимаю, что вы пытаетесь правильно, ваша карта должна быть типа
// v---- here ----v
std::map<Event, std::vector<std::function<void(SomeClass const &)>>> m_observers;
Где SomeClass
инкапсулирует данные, необходимые для возврата к обратным SomeClass
.
const void *
.... это определенно грязно! :-(