Is it possible to interleave template parameters inside of function call sites?
I effectively want to do implement the following, but I don't know how (psuedo code):
template <size_t... indices, typename... Ts>
void foo(const Things *things)
{
static_assert(sizeof...(indices) == sizeof...(Ts));
constexpr n = sizeof...(Ts);
bar(
indices[0], parse<Ts[0]>(things[0]),
indices[1], parse<Ts[1]>(things[1]),
...
indices[n-1], parse<Ts[n-1]>(things[n-1]));
}
Note: I know the following can be done (psuedo code):
template <size_t... indices, typename... Ts>
void foo(const Things *things)
{
static_assert(sizeof...(indices) == sizeof...(Ts));
constexpr n = sizeof...(Ts);
bar(
indices[0], indices[1], ..., indices[n-1],
parse<Ts[0]>(things[0]),
parse<Ts[1]>(things[1]),
...
parse<Ts[n-1]>(things[n-1]));
}
A partial solution I came up with is to add a swizzling component:
template <typename Func>
decltype(auto) swizzle()
{
return Func();
}
template <typename Func, typename T0>
decltype(auto) swizzle(size_t i0, T0 &&t0)
{
return Func(i0, std::forward<T0>(t0));
}
template <typename Func, typename T0, typename T1>
decltype(auto) swizzle(size_t i0, size_t i1, T0 &&t0, T1 &&t1)
{
return Func(i0, std::forward<T0>(t0), i1, std::forward<T1>(t1));
}
but I think I have to manually write each case per arity I want to consider.
A Variadic Argument can be a great fit in many cases but can also not be the right solution. This is due to its limitations that are important to know to decide whether or not it’s useful to use a Variadic Parameter. If an argument is defined implicitly as an array, it would be kind of logical to understand it’s possible to pass in an empty array:
The variadic function consists of at least one fixed variable and then an ellipsis (…) as the last parameter. int function_name (data_type variable_name, ...); Values of the passed arguments can be accessed through the header file named as: This enables access to variadic function arguments. This one accesses the next variadic function argument.
Variadic functions are functions that can take a variable number of arguments. In C programming, a variadic function adds flexibility to the program. It takes one fixed argument and then any number of arguments can be passed. The variadic function consists of at least one fixed variable and then an ellipsis (…) as the last parameter.
We can easily iterate through the arguments, find the size (length) of the template, can access the values by an index, and can slice the templates too. So basically, Variadic function templates are functions that can take multiple numbers of arguments.
Like this:
template <size_t... indices, typename... Ts>
void foo(const Things *things)
{
std::apply([](auto...args) {
bar(args...);
}, std::tuple_cat(std::make_tuple(indices, parse<Ts>(*(things++)))...));
}
If bar
is a lambda instead of a function template, you can just pass bar
directly as the first argument to std::apply
.
If you want to avoid copying the return values of parse<Ts>(*(things++))
, you can use std::forward_as_tuple
instead of std::make_tuple
.
One slightly more verbose alternative if the *(things++)
makes you uncomfortable is to use std::index_sequence
:
template <size_t... indices, typename... Ts>
void foo(const Things *things)
{
[=]<auto... Is>(std::index_sequence<Is...>) {
std::apply([](auto...args) {
bar(args...);
}, std::tuple_cat(std::make_tuple(indices, parse<Ts>(things[Is]))...));
}(std::index_sequence_for<Ts...>());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With