Hi,
Straight to the problem. Consider the situation, were a function accepts
parameter pack and something need to be done with each argument (for
example, we want to print each argument on a new line):
template
void print(Args&&... a) {
// print each a on a separate line
}
There's a known trick to do that:
template
void print(Args&&... a) {
(void) (int []){
0, (std::cout << a << std::endl, 0)...
};
}
But the syntax is not very readable (and I always forget it and search for
an example in Internet). I've tried to improve the syntax, and here's the
result:
template
void print(Args&&... a) {
expand_if {
std::cout << a << '\n'...
};
}
Compete source could be found here:
http://coliru.stacked-crooked.com/view?id=c2c59f22574671e5
Here's some more usage examples:
template
void printer_int(Args&&... args) {
expand {
std::cout << std::abs(args) << std::endl...,
std::cout << "Printing once again all the numbers: " << std::endl,
std::cout << " Once again " << std::abs(args) << std::endl...,
std::cout << "EOF Printing once again all the numbers." << std::endl
};
}
template
float sum(Args&&... args) {
float res = 0;
expand_if {
res += args...
};
return res;
}
I hope this would be helpful for someone or it could be used as an argument
for a proposal to extend C++ and allow simpler syntax:
template
void print(Args&&... a) {
std::cout << a << '\n'...;
}
P.S.: There was a nicer solution that newer required "_if" :
namespace detail {
struct expand_impl final {
template
constexpr inline
expand_impl(Arg&&...) noexcept
{}
};
}
template
using expand = detail::expand_impl;
But unfortunately there's no way to force the compiler to evaluate
expressions in constructor call from left to right. So it did not work on
GCC (but work on Clang).
--
Best regards,
Antony Polukhin