2015-02-20 9 views
6

Il codice seguente mostra una classe simile a un sindacato con un costruttore predefinito non banale (il membro viene inizializzato con un iniziatore iniziale o uguale), quindi se un costruttore predefinito per tale classe è impostato come predefinito, dovrebbe essere cancellato secondo §12.1/5 primo punto elenco. Cioè, la dichiarazione T t; non dovrebbe essere compilata, in quanto non esiste un costruttore predefinito per lo union T. Ma lo code compiles and executes in clang e GCC.AFAIK, il codice qui sotto non dovrebbe essere compilato, ma lo fa in clang e GCC. Cosa mi manca qui?

#include <iostream> 
union T 
{ 
    int y{1}; 
    float x; 
    char c; 
    T() = default; 
}; 

int main() 
{ 
    T t; 
    std::cout << t.y << '\n'; 
} 

EDIT

La mia domanda di cui sopra aveva ragione sbagliato fin dall'inizio, come l'unione T è non una classe un'unione simile. Sono venuto a sapere di §9.5/8 in C++ 11, che dice:

Una classe unione simile è un sindacato o di una classe che ha un'unione anonima come membro diretto. Una classe X simile a un sindacato ha un insieme di membri varianti. Se X è un'unione, i suoi membri varianti sono i membri dati non statici; altrimenti, i suoi membri variante sono i membri di dati non statici di tutte le unioni anonime che sono membri di X.

Ora, si consideri il frammento di seguito. Non viene compilato perché il costruttore predefinito per l'unione viene eliminato. Ma io ancora, non so quale punto di posta elettronica in §12.1/5 è responsabile per questo risultato. Si noti che, ancora una volta, l'unione non è una classe simil- e quindi, il primo punto elenco in §12.1/5 non si applica. Ma questo è ciò che il messaggio di errore dice sia in clang che in GCC. Vedi live example.

#include <iostream> 

union T{ 
    int y; 
    struct A{ int i; A():i{1} {} } a; 
}; 

int main() 
{ 
    T t; 
    std::cout << t.a.i << '\n'; 
} 
+0

"Un costruttore predefinito che è impostato come predefinito e non definito come eliminato è implicitamente definito quando è odoreggiato" Perché il tuo costruttore sembra essere odr-usato, non dovrebbe essere codice valido? – AndyG

+1

Compilare anche per VS 2015 Preview senza problemi. – PaulMcKenzie

+1

Qual è lo scopo di un'unione che non è possibile creare un'istanza in alcun modo? –

risposta

11

Il proiettile è

X è una classe Unione-like che ha un membro variante con un non banale costruttore predefinito

che viene analizzato come

X è una classe simile a un sindacato che ha (una variante membro t con un costruttore predefinito non banale)

cioè "con un costruttore di default non banale" si applica al tipo dell'organo variante, non X.

+0

Anche così, non è il costruttore predefinito per 'y' non banale? O forse il concetto di non banalità non si applica a un tipo built-in? – Ayrosa

+4

@Ayrosa 'y' è un' int', che come tutti i tipi primitivi non ha costruttori. Per non parlare di costruttori non banali.L'inizializzatore * brace-or-equal * * {1} 'nella definizione' int y {1}; 'non è un costruttore per' y', è usato per inizializzare 'y' nei costruttori * union * quando no è fornito un altro inizializzatore. In altre parole, la presenza di quel '{1}' significa che il tuo 'T() = default;' ha lo stesso effetto di 'T(): y {1} {}'. – Casey

+0

@ T.C. Ti dispiacerebbe commentare il mio ** Edit ** sopra? – Ayrosa

Problemi correlati