2016-02-02 30 views
11

N4191 espressioni piega proposte a C++. La definizione c'era quelAssociatività di espressioni di piega

(args + ...) 

è un fianco volte (cioè (((a0 + a1) + a2) + ...), e che

(... + args) 

è un destra-fold (cioè (... + (a8 + (a9 + a10))). Tuttavia, il documento rivisto N4295 invertito le definizioni di sinistra e pieghe unari destra

Domanda:. Qual è la logica sembra più intuitivo (almeno quando si è abituati a sinistra a destra alfabeti) per valutare 01.237.484,967 mila?da sinistra a destra.

+1

vorrei solo chiedere Richard o Andrew :) – SergeyA

+1

non so la loro logica, ma per me '(... + args)' si presenta come un sotto-espressione della piega a sinistra '(((... + a8) + a9) + a10) '. Analogamente '(args + ...)' sembra una sotto espressione di right fold '(a0 + (a1 + (a2 ...)))'. – user2079303

+0

@ user2079303 l'associatività a sinistra di 'a + b + c' è comunemente definita come (a + b) + c, si sta utilizzando l'opposto – TemplateRex

risposta

8

Dal commento di @cpplearner, ecco qualche archeologia da std-discussion

Il mercoledì, 4 febbraio 2015 alle 1:30, @T.C. wrote:

In N4295, che è stato effettivamente deliberato nello standard,

(... op e) è una piega unario sinistra;

(e op ...) è una piega destra unaria;

In N4191, tuttavia,

(e op ...) è chiamato una piega sinistra.

(... op e) è chiamato una piega destra.

Perché la svolta di 180 gradi?

E la risposta da @RichardSmith

La forma nel documento originale era semplicemente un errore di battitura. Ecco alcuni motivi per cui la definizione che è stata votata in standard è la corretta:

  1. Nella formulazione della norma, (e op ...) ha sottoespressioni della forma (e_i op <stuff>).Non ha sottoespressioni del modulo (<stuff> op e_i). Ciò è coerente con tutte le altre espansioni del pacchetto , in cui l'espansione comprende istanze ripetute del modello .

  2. (e op ... op eN), dove eN è un non-pack, deve avere eN come operando più interno per essere utile - cioè, deve essere (e1 op (e2 op (e3 op (... op eN)...))), non (...(((e1 op e2) op e3) op ...) op eN) - e viceversa per (e0 op ... op e). Ciò consente, per esempio, , (string() + ... + things) e (std::cout << ... << things) di funzionare. Per coerenza, anche (e op ...) deve essere (e1 op (e2 op (...))).

6

Non posso parlare per la proposta, ma le nuove definizioni scambiate mi sembrano naturali. Il mio fondamento logico per questo è che (... + args) è una sottoespressione di una piega a sinistra e (args + ...) è un'espressione secondaria di una piega a destra. Infatti, il primo è il segmento finale, e il secondo è il segmento iniziale dell'espressione (forse non sto usando la terminologia corretta).

Ecco come vorrei illustrare l'espansione della piega dalla sintassi:

Sinistra piegare

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

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

destro piegare

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

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