
C++1z will have fold expressions for this: (std::cout << a << '\n', ...); Add optional (void) cast for the paranoid. Also, your implementation doesn't work if the type of the expression is `void`, as far as I can see. On Fri, Jul 3, 2015 at 2:16 AM, Antony Polukhin <antoshkka@gmail.com> wrote:
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 <typename... Args> void print(Args&&... a) { // print each a on a separate line }
There's a known trick to do that:
template <typename... Args> 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<typename... Args> void print(Args&&... a) { expand_if<Args...> { 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<typename... Args> 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<typename... Args> float sum(Args&&... args) { float res = 0; expand_if<Args...> { 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<typename... Args> void print(Args&&... a) { std::cout << a << '\n'...; }
P.S.: There was a nicer solution that newer required "_if<Args..>" :
namespace detail { struct expand_impl final { template <class... Arg> constexpr inline expand_impl(Arg&&...) noexcept {} }; }
template <class... Arg> 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
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost