Let's say I have a function with the following signature:
void foo(std::string const& a, int b, char &c) {
...
}
How could I do something like param_type<foo, 3>::type
to get type == char?
Background:
I have a set of macros/TMP which generates a struct for converting a json object into a c++ value. I also have a set of structs representing each of the json types (primitives, array, object, etc). The main struct is defined by an X-macro, and the implementer must pass the parameter type (also used as the field type), the json type (one of the structs), and the key name into the X macros to define the fields.
I want to be able to separate the field type from the parameter type, so I can have something like std::optional<TField>
as the struct's field type and TField passed to the parse method. These macros are being used in many places, so I don't want to add another parameter to the X macros.
I tried using an auto
variable but as far as I know, something like the following isn't possible, which is why I want param_type
.
auto value;
parse(..., value);
field = value;
You can create a function traits with partial specialization:
template <auto func, std::size_t I>
struct param_type;
template <typename Ret, typename... Args, Ret (*func)(Args...), std::size_t I>
struct param_type<func, I>
{
using type = std::tuple_element_t<I, std::tuple<Args...>>;
};
// C-ellipsis version aka printf-like functions
template <typename Ret, typename... Args, Ret (*func)(Args..., ...), std::size_t I>
struct param_type<func, I>
{
using type = std::tuple_element_t<I, std::tuple<Args...>>;
};