折叠表达式的关联性 [英] Associativity of fold-expressions
问题描述
提出的 N4191 fold表达式到C ++。其定义是
(args + ...)
是左折叠(即(((a0 + a1)+ a2)+ ...)
,以及
(... + args)
是一个右折叠(即(... +(a8 +(a9 + a10)))
,修订文件 N4295
(args + ...)
。从@cpplearner的评论,这里有一些考古学从std-讨论
2015年2月4日星期三at 1 :30 AM, @TC写入 :
在N4295中,实际投票成为标准,
(... op e)
是一级左折;
(e op ...)
是一级右折;
然而,在N4191中,
(e op ...)
(... op e)
称为右折叠。
为什么要180度转?
RichardSmith
原始文件中的表单只是一个拼写错误。这里有一些
的原因,为什么被投入标准的定义是
正确的:
在标准的公式中,
(e op ...)
具有(e_i op< stuff>)$ c $的形式的子表达式c>。它没有
形式(< stuff> op e_i)
的子表达式。这与所有其他包
扩展一致,其中扩展包括
模式的重复实例。
(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(...))) / code>。
N4191 proposed fold-expressions to C++. The definition there was that
(args + ...)
is a left-fold (i.e. (((a0 + a1) + a2) + ...)
, and that
(... + args)
is a right-fold (i.e. (... + (a8 + (a9 + a10)))
. However, the revised paper N4295 reversed the definitions of left and right unary folds.
Question: what is the rationale? It seems more intuitive (at least when you are used to left-to-right alphabets) to evaluate (args + ...)
from left-to-right.
From the comment by @cpplearner, here's some archeology from std-discussion
On Wed, Feb 4, 2015 at 1:30 AM, @T.C. wrote:
In N4295, which was actually voted into the standard,
(... op e)
is a unary left fold;
(e op ...)
is a unary right fold;In N4191, however,
(e op ...)
is called a left fold.
(... op e)
is called a right fold.Why the 180-degree turn?
And the answer by @RichardSmith
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:
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.
(e op ... op eN)
, whereeN
is a non-pack, must haveeN
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 (...)))
.
这篇关于折叠表达式的关联性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!