De hecho, la versión final de C++ 11 no permite el uso de listas de inicializadores en el lado derecho (o en el lado izquierdo, para el caso) de un operador binario.
En primer lugar, listas de inicializadores no son expresiones como se define en el §5 de la Norma. Los argumentos de las funciones, así como de los operadores binarios, generalmente tienen que ser expresiones, y la gramática para las expresiones definidas en el §5 no incluye la sintaxis para las listas de inicio de llaves (es decir, listas de inicializadores puras; tenga en cuenta que un nombre de tipo seguido de una lista de inicio de llaves, como bar {2,5,"hello",7}
es una expresión, sin embargo).
Con el fin de ser capaz de utilizar inicializador listas puros convenientemente, la norma define varias excepciones, que se resumen en la nota siguiente (no normativo):
§8.5.4/1 [...] Nota: Lista-inicialización se puede utilizar
- como el inicializador en una definición de variable (8,5)
- como el inicializador en una nueva expresión (5.3.4)
- en una instrucción de retorno (6.6.3)
- como una función argumen t (5.2.2)
- como un subíndice (5.2.1)
- como argumento para una invocación de constructor (8.5, 5.2.3)
- como inicializador para un miembro de datos no estático (9.2)
- en una mem-inicializador (12.6.2)
- en el lado derecho de una asignación (5,17)
[...]
el cuarto punto anterior permite explícitamente initializer- pura listas como argumentos de funciones (que es por lo que operator<<(baz, {1, -2, "foo", 4, 5});
funciona), el quinto lo permite en expresiones de subíndices (es decir, como argumento de operator[]
, p. mymap[{2,5,"hello"}]
es legal), y el último elemento les permite en el lado derecho de asignaciones (pero no operadores binarios generales).
Hay hay tal excepción para los operadores binarios como +
, *
o <<
, por lo tanto, no se puede poner una lista de inicialización puro (es decir, uno que no está precedido por un nombre de tipo) a ambos lados de ellos.
En cuanto a las razones de esta , un draft/discussion paper N2215 por BS y Dos Reis desde 2007 proporciona un montón de información sobre muchos de los problemas con inicializador listas en varios contextos.Específicamente, hay una sección sobre operadores binarios (sección 6.2):
Considere usos más generales de las listas de inicializadores. Por ejemplo:
v = v+{3,4};
v = {6,7}+v;
Cuando consideramos los operadores como el azúcar sintáctica para las funciones, es natural considerar lo anterior equivale a
v = operator+(v,{3,4});
v = operator+({6,7},v);
lo tanto, es natural extender el uso de listas de inicializador de expresiones. Hay muchos usos en los que las listas de inicializadores combinadas con operadores son una notación "natural".
Sin embargo, no es trivial escribir una gramática LR (1) que permita el uso arbitrario de las listas de inicializadores. Un bloque también comienza con un {permitiendo así una lista de inicializadores ya que la primera entidad (a la izquierda) de una expresión llevaría al caos en la gramática.
Es trivial permitir listas de inicializadores como el operando de la derecha de operadores binarios, en los subíndices , y partes aisladas similares de la gramática. El verdadero problema es permitir ;a={1,2}+b;
como una declaración de asignación sin permitir también ;{1,2}+b;
. Sospechamos que permite inicializador enumera como de la derecha, pero tampoco [sic] como argumentos de la mano izquierda a la mayoría de los operadores es demasiado de un kludge, [...]
En otras palabras, de inicializador Listas de no están habilitados en el lado derecho porque no están habilitados en el lado izquierdo, y no están habilitados en el lado izquierdo porque eso representaría un desafío demasiado grande para los analizadores.
Me pregunto si el problema podría haberse simplificado eligiendo un símbolo diferente en lugar de llaves para la sintaxis de la lista de inicializadores.
Porque no has sobrecargado 'operator <<' para tomar una 'initializer_list <>' en el RHS ... ¿Cuál es tu pregunta real? – ildjarn
Esperaba que esto fuera equivalente a 'baz << bar {1, 2, 3, 4, 5};', pero parece que no hay conversión. – mavam
Si ese es el comportamiento que desea, tal vez debería intentar darle a 'bar' un constructor no explícito que tome una sola' initializer_list <> '. – ildjarn