Ассоциативность сгиб-выражений

N4191 предлагаемые сгиб-выражения для С++. Определение заключалось в том, что

(args + ...)

является левым краем (т.е. (((a0 + a1) + a2) + ...) и что

(... + args) 

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

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

Ответ 1

Из комментария @cpplearner, здесь некоторая археология из std-обсуждения

Вкл, 4 февраля 2015 года в 1:30 утра, @T.C. написал:

В N4295, который фактически был проголосован за стандарт,

(... op e) является унарной левой складкой;

(e op ...) является унарной правой складкой,

В N4191, однако,

(e op ...) называется левой складкой.

(... op e) называется правой складкой.

Почему поворот на 180 градусов?

И ответ @RichardSmith

Форма в оригинальной статье была просто опечаткой. Вот некоторые причины, по которым определение, которое было проголосовано в стандарте, является правильный:

  • В стандартной формулировке (e op ...) имеет подвыражения вида (e_i op <stuff>). Он не имеет подвыражений форма (<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 (...))).

Ответ 2

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

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

Левая складка

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

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

Правая справка

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

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