It’s now possible in C++17 with template<auto>:
template<auto Func>
struct FuncWrapper final
{
template<typename... Args>
auto operator()(Args &&... args) const
{
return Func(std::forward<Args>(args)...);
}
};
int add(int a, int b)
{
return a + b;
}
int main()
{
FuncWrapper<add> wrapper;
return wrapper(12, 34);
}
Demo: https://godbolt.org/g/B7W56t
You can use #ifdef __cpp_nontype_template_parameter_auto to detect compiler support for this in your code.
If you are able to use C++20 and you want better error messages, you can also use concepts:
template<typename T>
concept CanAddTwoNumbers = std::is_invocable_r_v<int, T, int, int>;
template<auto Func>
requires CanAddTwoNumbers<decltype(Func)>
struct AddTwoNumbersWrapper final
{
auto operator()(int a, int b) const
-> int
{
return std::invoke(Func, a, b);
}
};
int add(int a, int b)
{
return a + b;
}
int main()
{
AddTwoNumbersWrapper<add> wrapper;
return wrapper(12, 34);
AddTwoNumbersWrapper<123> bad; //error: constraint failure
}
Demo: https://gcc.godbolt.org/z/ai3WGH