Ассоциативность фолд-выражений

N4191 предложенные складные выражения для C ++. Определение там было

(args + ...)

является левой складкой (т.е. (((a0 + a1) + a2) + ...)и что

(... + args)

является правой складкой (т.е. (... + (a8 + (a9 + a10))), Тем не менее, пересмотренный документ N4295 поменял определения левых и правых одинарных складок.

Вопрос: что является обоснованием? Это кажется более интуитивным (по крайней мере, когда вы привыкли к алфавиту слева направо), чтобы оценить (args + ...) слева направо.

11

Решение

Из комментария @cpplearner, вот некоторая археология из std-Discussion

В среду, 4 февраля 2015 года, в 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

Другие решения

Я не могу говорить за предложение, но новые, поменявшиеся определения кажутся мне естественными. Мое обоснование для этого заключается в том, что (... + args) является суб-выражением левой складки, и (args + ...) является суб-выражением правой складки. На самом деле, первый — это последний сегмент, а второй — начальный сегмент выражения (возможно, я не использую правильную терминологию).

Вот как я бы проиллюстрировал расширение сгиба от синтаксиса:

Левый сгиб

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

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

Правый сгиб

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

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