Looking over the C++17 paper on folds, (and on cppreference), I'm confused as to why the choice was made to only work with operators? At first glance it seems like it would make it easier to expand (... + args)
by just shoving a +
token between the elements of args
, but I'm unconvinced this is a great decision.
Why can't a binary lambda expression work just as well and follow the same expansion as the latter above? It's jarring to me that a fold syntax would be added to a language without support for arbitrary callables, so does the syntax allow a way to use them that I'm just not seeing?
Update: This works for a variadic min()
function with clang
template <typename T>
struct MinWrapper {
const T& obj;
};
template <typename T, typename U, typename V=std::common_type_t<T,U>>
constexpr MinWrapper<V> operator%(
const MinWrapper<T>& lhs, const MinWrapper<U>& rhs) {
return {lhs.obj < rhs.obj ? lhs.obj : rhs.obj};
}
template <typename... Ts>
constexpr auto min(Ts&&... args) {
return (MinWrapper<Ts>{args} % ...).obj;
}
That's a great paper and a glorious language feature. If we bypass the standardese talk, which I'm not particularly fond of, I'd like to propose a workaround. Since I don't have a c++17 compiler (or a time machine) my answer will only be outlining, what I believe could be, a solution to providing fold expressions with arbitrary functions with the language status as is.
template<typename T>
struct wp {
T const& val;
// yes there should be constructors
};
template<typename Op, typename Ts...>
using wrapped_pack = make_wrapped<Op, Ts..>
wp<T>
template<typename T, typename U>
ret_val operator+(wp<T> const& lhs, wp<U> const& rhs) {...}
This would require an extra layer where the args
of the fold are transformed to wrapped arguments
An obvious shortcoming of the above is that it doesn't guarantee uniqueness (or scalability) : every fold with a custom callable would consume a built in operator overloading.
There should be hacks to vary the types based on the expression they're encountered in but I don't want to dive that deep into a thought experiment (eg using the type of Op
in the type of the wrapper already gives much more space to scale into).
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