Given a function passed as a template argument to a function, how can I determine the type of the of it’s first parameter?
For example:
template<auto Func>
void run_func(/* type of argument???? */ value) {
Func(value);
}
This particular use-case requires that the Func is a compile time constant. If possible I’d prefer to exact the type from Func rather than add another template argument as I wish to be able to refer to the function like so:
auto function_runner = &run_func<&func>;
Thanks
>Solution :
The type of the function is known at compile-time and can be obtained using std::remove_pointer_t<decltype(Func)>.
You would have to write a type trait that gives you information about the parameters like parameters<std::remove_pointer_t<decltype(Func)>>::type; see Get types of C++ function parameters
This looks something like:
template<typename Sig>
struct parameters;
// extremely imperfect solution because it doesn't work for noexcept,
// const, volatile, reference-qualified, or variadic functions
template<typename R, typename ...Args>
struct parameters<R(Args...)>
{
using type = std::tuple<Args...>;
};
// example is std::tuple<int, float>;
using example = parameters<void(int, float)>::type;
Making a proper solution is non-trivial though because there are 48 partial specializations you’d need to write to cover every kind of function, not just ones that have no cv or reference qualifier, and are not noexcept, like in the example.
In most cases, you don’t really need to know the types of parameters (or the first parameter). Maybe you can simply ask
Can I invoke this function with
int?
Rather than:
What is the type of the first parameter? Make sure that it’s
int.
The former question can be answered easily with std::is_invocable.
You can then use C++26 pack indexing, std::tuple_element, or some other means to get the first type in the tuple.