Ho una gerarchia di classi, che si riduce aEredità virtuale con il costruttore Inheritance
class Module { };
struct Port {
Module& owner;
Port(Module& owner) : owner(owner) {}
};
struct InPort : virtual Port { using Port::Port; };
struct OutPort : virtual Port { using Port::Port; };
struct InOutPort : InPort, OutPort { using Port::Port; };
Come potete vedere, io preferirei di creare alcune funzionalità di base, ed ereditare in un modello di diamante classico. Mi piacerebbe anche usare costruttore di ereditarietà per renderlo a prova di futuro possibile ...
Tuttavia, this does not work as written down above
prog.cpp: In function 'int main()':
prog.cpp:14:15: error: use of deleted function 'InOutPort::InOutPort(Module&)'
InOutPort p(m);
Anche la sostituzione della definizione di InOutPort
con una versione più esplicita is not enough:
struct InOutPort : InPort, OutPort { InOutPort(Module& m) : Port(m), InPort(m), OutPort(m) { } };
Invece I seem to have to write down everything explicitly for it to work::
struct InPort : virtual Port { InPort(Module& m) : Port(m) { } };
struct OutPort : virtual Port { OutPort(Module& m) : Port(m) { } };
struct InOutPort : InPort, OutPort { InOutPort(Module& m) : Port(m), InPort(m), OutPort(m) { } };
C'è un modo per combinare l'ereditarietà del constuctor con l'ereditarietà virtuale che sto trascurando?
In caso negativo, quale alternativa useresti?
Forse costruttori di modelli variadici che inoltrano perfettamente i propri argomenti a tutte le basi?
'InPort' e' OutPort' ereditano entrambi un costruttore che chiama il costruttore di default non dichiarato per 'Port' perché non sono entrambi una classe di derivazione più elevata. Il programma sarebbe mal formato se fossero stati chiamati. Per questo motivo, gcc decide di eliminare i costruttori corrispondenti in entrambe le classi. Clang non ha e non darà un errore sui costruttori anche quando le basi sono [inizializzate esplicitamente] (http://coliru.stacked-crooked.com/a/7c2963ba56e79793). Per inciso, clang dà anche un errore perché "Port" non è una classe di base diretta di "InOutPort" nella dichiarazione di utilizzo, mentre gcc lo ignora. – 0x499602D2
GCC infatti elimina i costruttori perché sarebbero mal formati, ma non per il motivo che ho precedentemente ipotizzato. Sembra che la dichiarazione d'uso [implicitamente odr-usi il costruttore predefinito] (http://coliru.stacked-crooked.com/a/490c0b5bb17fdc50). Il costruttore predefinito nella tua classe 'Port' non è dichiarato, quindi elimina il costruttore chiamante. Questo è un bug – 0x499602D2
Inoltre, accade solo se si tratta di una classe base virtuale. – 0x499602D2