2016-02-02 31 views
11

N4191向C++提出了折叠表达式。该定义有是折叠表达式的关联性

(args + ...) 

是左倍(即(((a0 + a1) + a2) + ...),并

(... + args) 

是一个对折(即(... + (a8 + (a9 + a10)))。但是,修改后的纸N4295左右颠倒的定义和右一元折叠

问题:什么是基本原理?看起来更直观(至少当你习惯了从左到右的字母)来评估(args + ...)从左到右。

+1

我只想问理查德·安德鲁或:) – SergeyA

+1

我不知道他们的理由,但对我来说'(... +参数)'看起来像左折'(的子表达式((... + a8)+ a9)+ a10)'。同样,'(args + ...)'看起来就像是'fold a'的子表达式(a0 +(a1 +(a2 ...)))''。 – user2079303

+0

@ user2079303'a + b + c'的左关联性通常定义为(a + b)+ c,您使用的是相反的 – TemplateRex

回答

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

6

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

这里是我会说明的褶皱从语法的扩展:

左折叠

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

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

右折

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

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