Простое предложение: получить вызываемое имя как выведенное имя типа, а не как std::function
Я имею в виду (добавив также совершенную пересылку)
template <typename F, typename ... Ts>
void callFunction(F const & func, Ts && ... pars)
{ func(std::forward<Ts>(pars)...); }
и, очевидно, назовите егоничего не объясняя
callFunction(&myFunc, "Hello world");
Это как дополнительное преимущество, позволяющее избежать преобразования вызываемого в std::function
.
В любом случае, я вижу две проблемы в вашем коде:
1) если вы получаете функционал в виде std::function
, получающего список типов аргументов (в данном случае список переменных, но не имеет значения для этой проблемы) в качестве списка аргументов тех же типов, вы должныбыть уверенным , что типы в двух списках соответствуют точно .
Это не ваш случай, потому что функция получает std::string const &
и вы передаете в качестве аргумента aстроковый литерал "Hello world"
, который является char const [12]
, который является другим типом.
Когда типы должны быть выведены, это вызывает ошибку компиляции, потому что компилятор не может выбирать между этими двумя типами.
Вы можете решить получение два список типов
template <typename ... Ts1, typename Ts2>
void callFunction (std::function<void(Ts1...)> const & function,
Ts2 && ... parameters)
{ function(std::forward<Ts2>(parameters)...); }
но теперь у нас есть вторая проблема
2) Вы передаете функцию указателя (&myFunc
), где callFunction()
ждутstd::function
.
У нас проблема с куриным яйцом, потому что &myFunc
можно преобразовать в std::function
, но не в std::function
.
Так что компилятор может 'выводит список типов Ts...
из &myFunc
, потому что не является std::function
и не может преобразовать &myFunc
в std::function
, потому что не знает список типов Ts...
.
Я вижу, что вы объяснили тип first в списке Ts...
, но этого недостаточно, потому что список Ts...
является переменным, поэтому компилятор не знает, что существует толькотип в списке Ts...
.
Простое решение этой проблемы - передать функцию как простой выведенный тип F
.
В противном случае, если вы написали callFunction()
сдва типа шаблонов списков, вы можете передать std::function
в функцию
std::function<void(std::string const &)> f{&myFunc};
callFunction(f, "Hello world");
, но я не думаю, что это удовлетворительное решение.