Infatti, la versione finale di C++ 11 non consente l'utilizzo di elenchi di inizializzatori sul lato destro (o sul lato sinistro, peraltro) di un operatore binario.
In primo luogo, gli elenchi di inizializzatore non sono espressioni come definito al §5 della norma. Gli argomenti delle funzioni, nonché di operatori binari, in genere devono essere espressioni e la grammatica per le espressioni definite nel § 5 non include la sintassi per brace-init-list (vale a dire di inizializzazione-list puri di notare che il typename seguito da un tutore-init-elenco come bar {2,5,"hello",7}
è espressione, però).
Per poter utilizzare puri inizializzazione liste convenientemente, lo standard definisce varie eccezioni, che sono riassunti nella seguente nota (non normativo):
§8.5.4/1 [...] Nota: List-inizializzazione può essere utilizzato
- come l'inizializzazione in una definizione della variabile (8.5)
- come l'inizializzazione in una nuova espressione (5.3.4)
- in una dichiarazione di ritorno (6.6.3)
- come argumen funzione t (5.2.2)
- come pedice (5.2.1)
- come argomento per una chiamata 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 una cessione (5.17)
[...]
il quarto punto sopra esplicitamente permette initializer- puro liste come argomenti di funzione (che è il motivo operator<<(baz, {1, -2, "foo", 4, 5});
opere), il quinto lo permette nelle espressioni pedice (vale a dire come argomento di operator[]
, ad es. mymap[{2,5,"hello"}]
è legale), e l'ultima voce permette loro sul lato destro della assegnazioni (ma non operatori binari generali).
Non v'è alcuna tale eccezione per gli operatori binari come+
, *
o <<
, quindi non si può mettere un lista di inizializzazione puro (vale a dire uno che non è preceduto da un TypeName) su entrambi i lati di esse.
Per quanto riguarda le ragioni di questo , un draft/discussion paper N2215 da Stroustrup e Dos Reis dal 2007 fornisce un sacco di comprensione molti dei problemi con inizializzazione liste in vari contesti.Nello specifico, esiste una sezione sugli operatori binari (sezione 6.2):
Considerare usi più generali degli elenchi di inizializzatori. Per esempio:
v = v+{3,4};
v = {6,7}+v;
Quando consideriamo operatori come zucchero sintattico per le funzioni, abbiamo naturalmente considerare quanto sopra equivale a
v = operator+(v,{3,4});
v = operator+({6,7},v);
E 'quindi naturale per estendere l'uso delle liste di inizializzazione 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 consente l'uso arbitrario di elenchi di inizializzatori. Un blocco inizia anche con un {consentendo così un elenco di inizializzazione come la prima entità (più a sinistra) di un'espressione porterebbe al caos nella grammatica.
È banale per consentire le liste di inizializzazione come operando destro di operatori binari, in indici, e parti isolate simili di grammatica. Il vero problema è consentire ;a={1,2}+b;
come una dichiarazione di assegnazione senza consentire anche ;{1,2}+b;
. Abbiamo il sospetto che permette inizializzatore elenca come a destra, ma non [sic] come argomenti a sinistra per la maggior parte degli operatori è troppo di un kludge, [...]
In altre parole, di inizializzazione-liste non sono abilitati sul lato destro perché non sono abilitati sul lato sinistro, e non sono abilitati sul lato sinistro perché questo avrebbe posto troppo grande una sfida per parser.
Mi chiedo se il problema potrebbe essere stato semplificato selezionando un simbolo diverso anziché le parentesi graffe per la sintassi dell'elenco inizializzatore.
Perché tu non sia sovraccarico operatore '' << Per fare un 'initializer_list <>' sul RHS ... Qual è la tua domanda reale? – ildjarn
Speravo che questo fosse equivalente a 'baz << bar {1, 2, 3, 4, 5};', ma sembra che non si sia verificata alcuna conversione. – mavam
Se questo è il comportamento che vuoi, forse dovresti provare a dare a 'bar' un costruttore non esplicito che prende un singolo' initializer_list <> '. – ildjarn