Consider the following (not working!) example:
#include <iostream>
template <typename type> void print(const type & item)
{
std :: cout << item << std :: endl;
}
template <typename... types> void printall(const types & ... items)
{
print(items)...;
}
int main()
{
printall(1, 2, "hello");
}
Here I have a function print
that simply prints out its argument, and a variadic function printall
that accepts a pack of arguments. Now, what I would like to do is to simply have printall
apply print
to each element of the pack items
. How can I get that done?
Note: I am not asking how to print a pack of values. I am aware of the existence of fold expressions and I know I could just throw the whole items
in std::cout
using them. Here print
is just an example, could be any function.
How can I get that done? This sounds like something that should remarkably simple to do and yet I couldn't find any (reasonable) syntax to do it.
What I would like to do is to simply have
printall
apply
As user @liliscent and user @max66 suggested in the comments, in C++11/ C++14 you can use the following hacky-way which act act like fold expressions in C++17.
SEE HERE
#include <iostream>
template <typename type> void print(const type& item)
{
std::cout << item << '\n';
}
template <typename... types>
void printall (const types&... items)
{
using dummy = int[];
(void)dummy { 0, (print(items), 0)... };
}
If the above does not look like good enough, provide a classical variadic templates overload as a wrapper/ helper between your printall()
and print()
functions, so that each template function arguments can be accessed in print()
.
SEE HERE
#include <iostream>
template <typename Type> void print(const Type& item)
{
std::cout << item << '\n'; // print each argument
}
namespace helper
{
void printall() {} // nontemplate overload for last call(i.e, no arguments call)
template<typename FirstArg, typename... Types>
void printall(const FirstArg& firstItem, Types&&... items)
{
::print(firstItem); // call print() for each argument
helper::printall(std::forward<Types>(items)...);// calls the same wrapper::printalll()
}
}
template <typename... Types> void printall(const Types& ... items)
{
helper::printall(items...); // calls the wrapper::printall()
}
However, if you have access to the C++17, just use fold expressions. That provides a clean(non-hacky) and less amount of code.
SEE HERE
template <typename type> void print(const type& item)
{
std::cout << item << '\n';
}
template <typename... types> void printall(const types&... items)
{
(print(items),...);
}
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