I want to prepare list of pairs of values from structure using variadic templates.
#include <vector>
struct foo
{
foo(int a, int b)
: a(a), b(b) {}
int a;
int b;
};
struct Msg
{
std::vector<int> valueArray;
};
template<typename... Args>
Msg func(Args... args)
{
Msg msg;
msg.valueArray = { sizeof...(args), (args.a)..., (args.b)... };
return msg;
}
int main() {
Msg msg = func(foo{1,2}, foo{3,4}, foo{5,6});
}
Msg which func will return will have valueArray = [3, 1, 3, 5, 2, 4, 6]
.
Is there any simple way to expand variadic paremeters in a way, where valueArray will look like valueArray = [3, 1, 2, 3, 4, 5, 6]
?
A variadic template is a class or function template that supports an arbitrary number of arguments. This mechanism is especially useful to C++ library developers: You can apply it to both class templates and function templates, and thereby provide a wide range of type-safe and non-trivial functionality and flexibility.
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.
Template classes and functions can make use of another kind of template parameter known as a non-type parameter. A template non-type parameter is a template parameter where the type of the parameter is predefined and is substituted for a constexpr value passed in as an argument.
Variadic templates are class or function templates, that can take any variable(zero or more) number of arguments. In C++, templates can have a fixed number of parameters only that have to be specified at the time of declaration. However, variadic templates help to overcome this issue.
The following is not as generic as I'd like to, but maybe it is sufficient for you:
template<typename Arr, std::size_t... Is>
Msg func2( const Arr& arr, std::index_sequence<Is...> )
{
Msg msg;
msg.valueArray = {
sizeof...(Is) / 2,
( ( Is % 2 == 0 ) ? std::get< Is / 2 >( arr ).a
: std::get< Is / 2 >( arr ).b )... };
return msg;
}
template<typename... Args>
Msg func(Args... args)
{
return func2( std::forward_as_tuple( args... ),
std::make_index_sequence< 2*sizeof...(Args) >() );
}
Live example
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