折叠表达式的相关性

时间:2016-02-02 20:28:53

标签: c++ language-lawyer c++17 associativity fold-expression

N4191提出了对C ++的fold-expressions。那里的定义是

(args + ...)

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

(... + args) 

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

问题:理由是什么?从左到右评估(args + ...)似乎更直观(至少当您习惯使用从左到右的字母表时)。

2 个答案:

答案 0 :(得分:8)

来自@cpplearner的评论,这是来自std-discussion的一些考古学

2015年2月4日星期三上午1:30,@T.C. wrote

  

在N4295中,实际上已经投入了标准,

     

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

     

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

     

然而,在N4191中,

     

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

     

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

     

为什么180度转弯?

@RichardSmith的回答

  

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

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

  2.   
  3. (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 (...)))

  4.   

答案 1 :(得分:6)

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

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

左折

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

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

右折

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

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