2014-09-08 16 views
19

Il codice C++ 11 seguente compila con successo sul mio GCC 4.8:C++ 11 costruttore di default privato

struct NonStack 
{ 
private: 
    NonStack() = default; 
public: 
    static NonStack* Create(){ 
    return new NonStack; 
    } 
}; 
NonStack a; 

int main() { } 

Tuttavia la seguente dà un errore di compilazione:

struct NonStack 
{ 
private: 
    NonStack(){} 
}; 

NonStack a; 

int main() { } 

Perché la prima uno ha successo? Il costruttore privato predefinito non dovrebbe proibire la creazione di un oggetto tramite NonStack a;?

+2

Il tuo codice fa davvero [compile] (http://coliru.stacked-crooked.com/a/55199811d96f1af7) su gcc4.8, ma 4.9 lo rifiuta (come dovrebbe). – Praetorian

+8

Questa domanda sarebbe meglio se ci fosse una domanda in esso. –

+0

Puoi anche '= eliminare;' il costruttore. Dovrebbe comportarsi come previsto. – glampert

risposta

17

Questo è il bug gcc 54812, il compilatore non rispetta gli specificatori di accesso per le funzioni dei membri speciali esplicitamente predefinite. Il bug 56429, che è contrassegnato come duplicato di quello precedente, ha un test case che è quasi identico all'esempio nella domanda.

Le soluzioni sono l'aggiornamento a gcc4.9, che risolve il problema. Oppure crea un corpo vuoto per il costruttore, invece di impostarlo in modo esplicito come hai fatto nel secondo esempio.

+3

Nota: il bug si collega a [core language issue 1507] (http: //www.open- std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1507). Non era un bug in GCC. Lo standard usava davvero dire che dal momento che il costruttore era banale, il costruttore non veniva chiamato, e se il costruttore non viene chiamato, il fatto che sia "privato" non è un problema. – hvd

+0

@hvd Concordato che il costruttore privato banale è inaccessibile ma ben formato era un difetto dello standard, ma il bug report gcc indica ancora un bug perché sta applicando quella logica ai distruttori banali inaccessibili. La risposta potrebbe essere formulata meglio, e la aggiornerò tra un po '. – Praetorian

+0

Ah, mi sono perso, lo standard ha avuto una formulazione appropriata per questo più a lungo. Forse di interesse, lo standard non sembra avere ancora il divieto di eliminare un puntatore a un tipo di classe incompleta che avrebbe un distruttore banale inaccessibile, è solo un comportamento indefinito se il distruttore è in realtà non banale. – hvd

Problemi correlati