В вашем коде есть некоторые проблемы.
В произвольном порядке
(1) BindAction()
получает std::function<void(T*, Args...)> const &
, для некоторых типов T
e Args...
быть выведен, но вы передаете ему &Simulation::Test
, поэтому указатель на (static
?) метод класса / структуры, который не является std::function
.
Вы передаете указателькоторый может быть преобразован в std::function
, но не является std::function
.
Этакая проблема с яйцом и курицей: компилятор не может преобразовать указатель в std::function
, потому что не знаеттипы Args...
и не могут выводить типы Args...
, потому что не получает std::function
(2), вам нужны два различных вариационных списка типов аргументов: список Args1...
дляАргумент std::function
и второй список Args2...
для полученных аргументов (args...
).
См. пример вашего вызова
void Test(float f, std::string s, int i);
BindAction<Simulation>("Test", this, &Simulation::Test, 5.f, "a string", 2);
Метод Test()
получает a float
, std::string
и int
;но BindAction()
получает float
, char const [9]
и int
.
Если вы используете один список Args...
, компилятор не может вывести типы, поскольку имеет два разных спискатипы.
(3) не уверен, но ... ваш BindAction()
является методом static
, но использует (если я правильно понимаю) член объекта (m_action
)
(4) ваш метод BindAction()
является методом void
, но возвращает функцию [исправлено]
Предложения:
(a) получает вызываемый какСам шаблонный тип, без определения типов аргументов
(b) получить список аргументов в качестве универсальных ссылок и использовать пересылку шаблонов
Чтобы показать упрощенный пример, что-то следующее
#include <functional>
#include <iostream>
template <typename F, typename ... As>
static auto BindAction (F const & func, As && ... args)
{ return std::bind(func, std::forward<As>(args)...); }
void Test(float f, std::string s, int i)
{ std::cout << "f[" << f << "], s[" << s << "], i[" << i << "]" << std::endl; }
int main ()
{
auto ba = BindAction(Test, 5.f, "a string", 2);
std::cout << "post BindAction(), pre ba()\n";
ba();
}