Generic folding without C++17 fold expressions

After commenting on Baptiste Wicht’s blog post on C++ 17 fold expressions (this post is an extension of my comment) and reading N4295, I was left wondering what purpose they fulfill.

C++17 fold expressions exist in four forms (although the last two are syntactically identical, the only difference being which expression is an unexpanded parameter pack):

This is certainly cleaner than writing a recursive function each and every time we want to fold a parameter pack using a binary operator. Nice, right? But what about other binary functions? Why limit a fold only to fixed operators? Sure, you could write a wrapper that defines a binary operator as the application of an arbitrary function as this Stack Overflow answer suggests, but that seems less than clean. Another thing that bothers me, is that the syntax does not directly suggest if a left or right fold is performed.

Let’s approach this from another direction. What can you use right now with a C++14 compiler? By using automatic return type deduction and passing a functor, it is fairly easy to write generic left and right fold functions:

This might seem to complicate usage with simple operators but  <functional> already offers generic functors for most operators (except shifts and augmented assignments), so the equivalent to the first block of code would be:

There are a couple of possibilities of how this could be extended, for example a neutral_value<Functor> type trait or template variable could be introduced to allow for folds of empty parameter packs (such as fold expressions allow for some operators).

There might be some use cases in Concepts as Kerrek SB suggested, but it is unclear to me which ones these would be. I could not find anything in the corresponding papers.

Does this mean I am opposed to fold expressions? Not necessarily. There’s nothing wrong with a little syntactic sugar. Range based for loops could also have been implemented using only lambda and a template function.  constexpr functions can often be replaced with template metaprogramming, but using  constexpr functions is usually easier on the compiler and results in shorter compile times.

Leave a Reply

Your email address will not be published. Required fields are marked *