https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71502
Sleep tight pupper <horridminded at mailinator dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |horridminded at mailinator dot com --- Comment #3 from Sleep tight pupper <horridminded at mailinator dot com> --- This is not a bug. See this discussion: https://groups.google.com/a/isocpp.org/forum/#!msg/std-discussion/Sxbm2CEpMv4/CbfJtKGLEAkJ and explanation by the author of the proposal, Richard Smith. > > In N4295 [1], which was actually voted into the standard, > > (... op e) is a > >> *unary left fold;*(e op ...) is a *unary right fold;* > > In N4191[2], however, > >> (e op ...) is called a *left fold*. > >> (... op e) is called a *right fold*. > > Why the 180-degree turn? > The form in the original paper was simply a typo. Here are some reasons why > the definition that was voted into the standard is the correct one: > 1) In the standard's formulation, (e op ...) has subexpressions of the > form (e_i op <stuff>). It does not have subexpressions of the form (<stuff> > op e_i). This is consistent with all other pack expansions, where the > expansion comprises repeated instances of the pattern. > 2) (e op ... op eN), where eN is a non-pack, must have eN as the innermost > operand in order to be useful -- that is, it must be (e1 op (e2 op (e3 op > (... op eN)...))), not (...(((e1 op e2) op e3) op ...) op eN) -- and vice > versa for (e0 op ... op e). This allows, for instance, (string() + ... + > things) and (std::cout << ... << things) to work. For consistency, (e op > ...) must also be (e1 op (e2 op (...))).