问题 折叠表达式的相关性


N4191 提出了C ++的fold-expressions。有那样的定义

(args + ...)

是左折(即 (((a0 + a1) + a2) + ...), 然后

(... + args) 

是右折(即 (... + (a8 + (a9 + a10)))。但是,修改后的论文 N4295 颠倒了左右一元褶皱的定义。

:理由是什么?它似乎更直观(至少当你习惯于从左到右的字母表)进行评估 (args + ...) 从左到右。


4518
2018-02-02 20:28


起源

我只想问理查德或安德鲁:) - SergeyA
我不知道他们的理由,但对我而言 (... + args) 看起来像左侧折叠的子表达式 (((... + a8) + a9) + a10) 。同样地 (args + ...) 看起来像是右折叠的子表达式 (a0 + (a1 + (a2 ...)))。 - user2079303
@ user2079303左关联性 a + b + c  通常被定义为(a + b)+ c,你正在使用相反的 - TemplateRex
另外,考虑与二进制折叠的一致性。你真的想要 (std::cout << ... << args) 上班... - T.C.
理查德的回答。 - cpplearner


答案:


从@cpplearner的评论中,这里有一些来自std-discuss的考古学

2015年2月4日星期三凌晨1:30, @ T.C。写

在实际投入标准的N4295中,

(... op e) 是一个一元的左折;

(e op ...) 是一个一元的右折;

但是,在N4191中,

(e op ...) 被称为左折。

(... op e) 被称为右折。

为什么180度转弯?

而@RichardSmith的回答

原始论文中的表格只是一个错字。这里有一些   投票成标准的定义是什么原因   正确一个:

  1. 在标准的配方中, (e op ...) 有表格的子表达式 (e_i op <stuff>)。它没有子表达式   形成 (<stuff> op e_i)。这与所有其他包装一致   扩展,其中扩展包括重复的实例   模式。

  2. (e op ... op eN),哪里 eN 是一个非包装,必须有 eN 作为最里面的操作数,为了有用 - 也就是说,它必须是    (e1 op (e2 op (e3 op (... op eN)...)))不是 (...(((e1 op e2) op e3) op ...) op eN)  - 反之亦然 (e0 op ... op e)。这允许,   例如, (string() + ... + things) 和 (std::cout << ... << things) 上班。为了保持一致 (e op ...) 也必须如此 (e1 op (e2 op (...)))


8
2018-02-02 21:54





我不能代表这个提议,但新的交换定义对我来说似乎很自然。我的理由是 (... + args) 是左折叠的子表达式,和 (args + ...) 是右折叠的子表达式。事实上,前者是最后一段,而后者是表达式的初始段(我可能没有使用正确的术语)。

以下是我将如何从语法中说明折叠的扩展:

左折

                     (... + args)
             (... + args) + a999)
     (... + args) + a998) + a999)

((...((a0 + a1) + a2)...) + a999)

右折

(args + ...)
(a0 + (args + ...)
(a0 + (a1 + (args + ...)

(a0 + (...(a997 + (a998 + a999))...))

6