|
Boost : |
Subject: [boost] Metaprogramming: parameter pack expansion/evaluation trick
From: Antony Polukhin (antoshkka_at_[hidden])
Date: 2015-07-03 02:16:44
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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk