Elenchi di inizializzatori e RHS degli operatori

Non capisco perché gli elenchi di inizializzatori non possano essere usati sull’RHS di un operatore. Prendere in considerazione:

class foo { }; struct bar { template bar(T const&...) { } }; foo& operator<<(foo& f, bar const&) { return f; } int main() { foo baz; baz << {1, -2, "foo", 4, 5}; return 0; } 

L’ultimo Clang (gcc pure) si lamenta:

 clang.cc:14:9: error: initializer list cannot be used on the right hand side of operator '<<' baz << {1, -2, "foo", 4, 5}; ^ ~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~ 

Perché lo standard C ++ lo vieterebbe? O mettere in modo diverso, perché questo fallisce al contrario di

 baz << bar{1, -2, "foo", 4, 5}; 

?

In effetti, la versione finale di C ++ 11 non abilita l’uso di elenchi di inizializzatori sul lato destro (o sul lato sinistro, per quella questione) di un operatore binario.

Innanzitutto, le liste di inizializzazione non sono espressioni come definite nel §5 dello Standard. Gli argomenti delle funzioni, come pure degli operatori binari, in genere devono essere espressioni, e la grammatica per le espressioni definite in §5 non include la syntax per le liste di brace-init (cioè le liste di inizializzazione pure, si noti che un nome di tipo seguito da una lista brace-init-list, come bar {2,5,"hello",7} è un’espressione, però).

Per poter utilizzare comodamente le liste di inizializzazione pure, lo standard definisce varie eccezioni, che sono riassunte nella seguente nota (non normativa):

§8.5.4 / 1 […] Nota: è ansible utilizzare l’inizializzazione dell’elenco
– come inizializzatore in una definizione di variabile (8.5)
– come inizializzatore in una nuova espressione (5.3.4)
– in una dichiarazione di ritorno (6.6.3)
– come argomento della funzione (5.2.2)
– come pedice (5.2.1)
– come argomento per una chiamata del costruttore (8.5, 5.2.3)
– come inizializzatore per un membro dati non statico (9.2)
– in un mem-inizializzatore (12.6.2)
– sul lato destro di un incarico (5.17)
[…]

Il quarto elemento sopra esplicitamente consente pure di inizializzare-liste come argomenti di funzione (che è il motivo per cui l’ operator<<(baz, {1, -2, "foo", 4, 5}); funziona), il quinto lo consente nelle espressioni di pedice (cioè come argomento operator[] , ad es. mymap[{2,5,"hello"}] è legale) e l'ultimo elemento li consente sul lato destro delle assegnazioni (ma non sugli operatori binari generali).

Non esiste una tale eccezione per gli operatori binari come + , * o << , quindi non è ansible inserire una lista di inizializzazione pura (cioè una che non è preceduta da un nome tipografico) su entrambi i lati.

Per quanto riguarda i motivi , un documento di discussione / N2215 di Stroustrup e Dos Reis del 2007 fornisce molte informazioni su molti dei problemi con elenchi di inizializzatori in vari contesti. In particolare, c'è una sezione sugli operatori binari (sezione 6.2):

Prendi in considerazione usi più generali degli elenchi di inizializzatori. Per esempio:

 v = v+{3,4}; v = {6,7}+v; 

Quando consideriamo gli operatori come zucchero sintattico per le funzioni, consideriamo naturalmente il precedente equivalente a

 v = operator+(v,{3,4}); v = operator+({6,7},v); 

È quindi naturale estendere l'uso degli elenchi di inizializzatori alle espressioni. Ci sono molti usi in cui le liste di inizializzatori combinate con gli operatori sono una notazione "naturale".
Tuttavia, non è banale scrivere una grammatica LR (1) che consenta l'uso arbitrario degli elenchi di inizializzatori. Un blocco inizia anche con un {consentendo così un elenco di inizializzazione come la prima entity framework (più a sinistra) di un'espressione porterebbe al caos nella grammatica.
È banale consentire gli elenchi di inizializzatori come l'operando di destra degli operatori binari, in pedici e parti simili della grammatica. Il vero problema è consentire ;a={1,2}+b; come una dichiarazione di assegnazione senza anche consentire ;{1,2}+b; . Sospettiamo che consentire elenchi di inizializzatori come la mano destra, ma né [sic] come argomenti a mano sinistra per la maggior parte degli operatori sia troppo di un kludge, [...]

In altre parole, le liste di inizializzazione non sono abilitate sul lato destro perché non sono abilitate sul lato sinistro , e non sono abilitate sul lato sinistro perché ciò avrebbe posto una sfida troppo grande per i parser .

Mi chiedo se il problema potrebbe essere stato semplificato selezionando un simbolo diverso invece di parentesi graffe per la syntax dell'elenco inizializzatore.