Definizione della class annidata al di fuori della class esterna, mentre la class esterna contiene l’istanza della class interna

C ++

Come posso inserire la definizione di una class interna (nidificata) al di fuori della sua definizione della class esterna (che racchiude), in cui la class esterna ha almeno un’istanza della class interna come membro dei dati? Ho cercato ma la risposta SO più pertinente che ho trovato, definizione di class annidata nel file sorgente , non ha un esempio in cui la class esterna ha un object interno come membro dati. Ho seguito quella risposta, per quanto riguarda la dichiarazione ma non la definizione della class interna all’interno della definizione della class esterna, ma il mio codice è ancora rotto:

struct Outer { struct Inner; Inner myinner; Outer() : myinner(2) {} }; struct Outer::Inner { Inner(int n) : num(n) {} int num; }; int main() { Outer myouter; } 

Viene visualizzato l’errore error C2079: 'Outer::myinner' uses undefined struct 'Outer::Inner' in VC11.

E perché il codice non ha un effetto equivalente a quello della versione in cui Inner è definito all’interno della definizione di Outer , come nel seguente codice di lavoro?

 struct Outer { struct Inner { Inner(int n) : num(n) {} int num; } myinner; Outer() : myinner(2) {} }; 

Questa è una bandiera rossa, ma puoi farlo usando un modello falso.

 template< typename = void > struct Outer_temp { struct Inner; Inner myinner; Outer_temp() : myinner(2) {} }; typedef Outer_temp<> Outer; // Hide template from user. template< typename v > struct Outer_temp< v >::Inner { Inner(int n) : num(n) {} int num; }; int main() { Outer myouter; } 

Inner all’interno del modello è di tipo dipendente, quindi non è necessario che sia completo quando si definisce un’istanza, in un membro o in qualsiasi altro contesto. Deve solo essere completo una volta eseguita l’istanziazione, in questo caso da main .

Non riesco a immaginare una buona ragione per farlo, ma è così.

Le classi annidate non dovrebbero essere utilizzate per l’organizzazione del programma. La nidificazione suggerisce una dipendenza concettuale: “L’interno non può esistere se non in un contesto fornito da Outer”. Sebbene sia comune, ad esempio, che una class nodo contenitore sia annidata nel contenitore, ciò può causare problemi. L’idioma di SCARY è uno stile di design che ripudia tale organizzazione e migliora la genericità.

TL; DR: definisce le due classi in modo indipendente e le collega a un typedef annidato.