Orden de evaluación de los elementos en la inicialización de la lista

En el otro tema , @Dietmar dio esta solución:

template  std::tuple parse(std::istream& in) { return std::tuple{ T(in)... }; } 

declarando que,

El uso de la inicialización de llaves funciona porque el orden de evaluación de los argumentos en una lista de inicializadores de llaves es el orden en que aparecen . (enfatiza el mío)

El texto relevante del Estándar C ++ (n3485) es,

Dentro de la lista de inicialización de una lista inicial arrinconada, las cláusulas inicializadoras, incluidas las que resultan de las expansiones de paquetes (14.5.3), se evalúan en el orden en que aparecen. Es decir, cada cálculo de valor y efecto secundario asociado con una cláusula de inicializador dada se secuencia antes de cada cálculo de valor y efecto secundario asociado con cualquier cláusula de inicializador que lo sigue en la lista separada por comas de la lista de inicializadores. [Nota: Este orden de evaluación se mantiene independientemente de la semántica de la inicialización; por ejemplo, se aplica cuando los elementos de la lista de inicializadores se interpretan como argumentos de una llamada de constructor, aunque ordinariamente no hay restricciones de secuencia en los argumentos de una llamada. -Finalizar nota]


Así que traté de probar esto con el siguiente código:

 template struct A { std::string data; A(std::istream & stream) { stream >> data; } friend std::ostream& operator<<(std::ostream & out, A const & a) { return out << "A"<<N<<"::data = " << a.data; } }; typedef A A1; typedef A A2; template void test(std::istream & stream) { std::tuple args { Args(stream)... }; std::cout << std::get(args) << std::endl; std::cout << std::get(args) << std::endl; } int main() { std::stringstream ss("A1 A2"); test(ss); } 

Rendimiento esperado:

 A1::data = A1 A2::data = A2 

Salida real:

 A1::data = A2 A2::data = A1 

¿Hice algo mal en mi código de prueba? Cambié mi código a esto:

 std::stringstream ss("A1 A2"); std::tuple args{A1(ss), A2(ss)}; std::cout << std::get(args) << std::endl; std::cout << std::get(args) << std::endl 

Mismo resultado que antes. MinGW (GCC) 4.7.0 mi código con MinGW (GCC) 4.7.0 y 4.7.2 . Incluso ideone da esta salida .

¿Es un error en el comstackdor?

Respondiendo mi propia pregunta. Eliminar la pregunta no sería una buena idea, ya que alguien podría tener la misma pregunta en el futuro.

Sí. Es un error en el comstackdor de GCC.

  • Error 51253 – [C ++ 11] [DR 1030] Orden de evaluación (relación secuenciada-antes) entre cláusulas-inicializador en lista-inicial-arriesgada

tomado del comentario de @Johannes Schaub a la pregunta.