Возможный способ - использовать специализацию шаблона
template <typename>
struct myFunc;
template <typename R, typename ... Args>
struct myFunc<R(*)(Args...)>
{
// ...
};
, но таким образом вы перехватываете (в качестве параметра шаблона) тип указателя функции, а не указателя функциисам;поэтому вам нужно каким-то образом передать указатель на функцию (конструктор?).
Также обратите внимание, что если вы хотите использовать идеальную пересылку, вы должны преобразовать operator()
в методе шаблона, получающем аргументы как универсальные ссылки(&&
).
Что-то следующее
template <typename ... As>
R operator() (As && ... args) const
{
return fun(std::forward<As>(args)...);
}
, где fun
- указатель типа R(*)(Args...)
.
Ниже приведен полный пример компиляции
#include <iostream>
#include <utility>
int foo (int, long)
{ return 42; }
template <typename>
struct myFunc;
template <typename R, typename ... Args>
struct myFunc<R(*)(Args...)>
{
using funPnt = R(*)(Args...);
funPnt fun = nullptr;
myFunc (funPnt f0) : fun{f0}
{ }
template <typename ... As>
R operator() (As && ... args) const
{
return fun(std::forward<As>(args)...);
}
};
int main ()
{
myFunc<decltype(&foo)> mf0{&foo};
std::cout << mf0(1, 2l) << std::endl;
}
Если вам действительно нужна функция указателя в качестве параметра шаблона (но, таким образом, каждая функция определяет свой тип; это может быть хорошим или плохим в соответствии с вашими потребностями), вы можете написатьmyFunc
структура получает перед типом (тот же тип указателя) и затем значение этого типа.
Итак
template <typename T, T>
struct myFunc;
template <typename R, typename ... Args, R(*Func)(Args...)>
struct myFunc<R(*)(Args...), Func>
{
template <typename ... As>
R operator() (As && ... args) const
{
return Func(std::forward<As>(args)...);
}
};
, который может быть объявлен
myFunc<decltype(&foo), foo> mf0;
Если вы можете использовать C ++ 17, вы можете упростить использование auto
для типа значений шаблона;так что вы можете избежать типа
template <auto>
struct myFunc;
template <typename R, typename ... Args, R(*Func)(Args...)>
struct myFunc<Func>
{
template <typename ... As>
R operator() (As && ... args) const
{
return Func(std::forward<As>(args)...);
}
};
и создать объект myFunc
следующим образом
myFunc<&foo> mf0;
Добавление: если вы можете использовать C ++ 17, вы можете определитьруководство по выводу для первого примера (указатель как член, а не как параметр значения шаблона)
template <typename R, typename ... Args>
myFunc (R(*)(Args...)) -> myFunc<R(*)(Args...)>;
, поэтому вместо
myFunc<decltype(&foo)> mf0{&foo};
вы можете просто написать
myFunc mf0{&foo};
Не по теме: надеюсь, вы знаете, что изобретаете велосипед.Как предполагает NathanOliver, стандарт обеспечивает std::function
.