Inizializzazione di aggregazione C ++ 11 per classi con inizializzatori di membri non statici

È consentito in standard:

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

Questa class è ancora aggregata? clang accetta questo codice, ma gcc no.

In C ++ 11 con gli inizializzatori dei membri in class rende struct / class non un aggregato, tuttavia questo è stato modificato in C ++ 14. Questo è qualcosa che ho trovato sorprendente quando ho iniziato a farlo, la logica di questa restrizione è che gli inizializzatori in-class sono piuttosto simili a un costruttore definito dall’utente, ma l’argomento contatore è che nessuno si aspetterebbe davvero che l’aggiunta di inizializzatori in class dovrebbe rendere la loro class / struttura un non aggregato, di sicuro non l’ho fatto.

Dalla bozza di standard C ++ 11 sezione 8.5.1 Aggregati ( enfatizzare il mio futuro ):

Un aggregato è un array o una class (clausola 9) senza costruttori forniti dall’utente (12.1), nessun inizializzatore brace-or-equal per membri di dati non statici (9.2), nessun membro di dati non statici privato o protetto (Clausola 11), nessuna class base (clausola 10) e nessuna funzione virtuale (10.3).

e in C ++ 14 lo stesso paragrafo recita:

Un aggregato è un array o una class (clausola 9) senza costruttori forniti dall’utente (12.1), nessun membro di dati non statici privato o protetto (clausola 11), nessuna class di base (clausola 10) e nessuna funzione virtuale (10.3 ).

Questo cambiamento è coperto da N3605: inizializzatori e aggregati di membri che presenta il seguente riassunto:

Bjarne Stroustrup e Richard Smith hanno sollevato un problema sull’inizializzazione degli aggregati e gli inizializzatori dei membri non funzionavano insieme. Questo documento propone di risolvere il problema adottando la formulazione proposta da Smith che rimuove una restrizione secondo cui gli aggregati non possono avere inizializzatori di membri .

Questo commento riassume sostanzialmente la riluttanza a consentire loro di essere aggregati:

Gli aggregati non possono avere costruttori definiti dall’utente e gli inizializzatori dei membri sono essenzialmente una sorta di costruttore (elemento) definito dall’utente (vedere anche Core Defect 886). Non sono contro questa estensione, ma ha anche implicazioni su ciò che è in realtà il nostro modello di aggregati. Dopo l’accettazione di questa estensione mi piacerebbe sapere come insegnare cosa sia un aggregato.

La versione rivista N3653 è stata adottata nel maggio 2013 .

Aggiornare

emsr sottolinea che G ++ 5.0 ora supporta gli aggregati C ++ 14 con inizializzatori di membri di dati non statici che utilizzano std=c++1y o -std=c++14 :

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

Guardalo dal vivo .