Inicialización agregada C ++ 11 para clases con inicializadores de miembros no estáticos

Está permitido en estándar:

struct A { int a = 3; int b = 3; }; A a{0,1}; // ??? 

¿Esta clase todavía es agregada? clang acepta este código, pero gcc no.

En C ++ 11 tener inicializadores de miembro en clase hace que la estructura / clase no sea un agregado; sin embargo, esto se modificó en C ++ 14. Esto es algo que encontré sorprendente cuando me topé por primera vez, la razón de esta restricción es que los inicializadores de clase son bastante similares a un constructor definido por el usuario, pero el argumento del contador es que nadie realmente espera que la adición de inicializadores en clase deba hacer su clase / estructura no es agregada, seguro que no.

Del borrador de C ++ 11, sección estándar 8.5.1 Agregados ( énfasis mío en el futuro ):

Un agregado es una matriz o una clase (Cláusula 9) sin constructores proporcionados por el usuario (12.1), sin inicializadores ortográficos para miembros de datos no estáticos (9.2), sin miembros de datos no estáticos protegidos o privados (Cláusula 11), sin clases base (Cláusula 10), y sin funciones virtuales (10.3).

y en C ++ 14 el mismo párrafo dice:

Un agregado es una matriz o una clase (Cláusula 9) sin constructores proporcionados por el usuario (12.1), sin miembros de datos no estáticos protegidos o privados (Cláusula 11), sin clases base (Cláusula 10) y sin funciones virtuales (10.3 )

Este cambio está cubierto en N3605: Inicializadores y agregados de miembros que tiene el siguiente resumen:

Bjarne Stroustrup y Richard Smith plantearon un problema acerca de la inicialización agregada y la inicialización de miembros que no funcionaba en conjunto. Este documento propone solucionar el problema mediante la adopción de la redacción propuesta por Smith que elimina la restricción de que los agregados no pueden tener iniciadores de miembros .

Este comentario básicamente resume la reticencia a permitir que sean agregados:

Los agregados no pueden tener constructores definidos por el usuario y los inicializadores de miembros son esencialmente algún tipo de constructor (elemento) definido por el usuario (consulte también el defecto principal 886). No estoy en contra de esta extensión, pero también tiene implicaciones en lo que realmente es nuestro modelo de agregados. Después de la aceptación de esta extensión, me gustaría saber cómo enseñar qué es un agregado.

La versión revisada N3653 fue adoptada en mayo de 2013 .

Actualizar

emsr señala que G ++ 5.0 ahora admite agregados C ++ 14 con inicializadores de miembros de datos no estáticos usando std=c++1y o -std=c++14 :

 struct A { int i, j = i; }; A a = { 42 }; // aj is also 42 

Véalo trabajando en vivo .