Heads up, proprio come ha detto Jonathan Wakely, C++ 17 ha modificato questo comportamento. Ora gli argomenti predefiniti nell'elenco dei parametri vengono ereditati.
Vale a dire, se avessimo il seguente costruttore in una classe denominata Base
,
struct Base {
Base(int a, int b, int c = 1, int d = 2, int e = 3) {}
};
poi per quel costruttore sopra, questi sono quelli che sono 'iniettati' nella classe derivata in C + corrispondente + 11/C++ 14:
struct Derived : Base {
using Base::Base;
/*
C++11/C++14:
Derived::Derived(int a, int b) : Base(a, b) {}
Derived::Derived(int a, int b, int c) : Base(a, b, c) {}
Derived::Derived(int a, int b, int c, int d) : Base(a, b, c, d) {}
Derived::Derived(int a, int b, int c, int d, int e) : Base(a, b, c, d, e) {}
*/
};
mentre quello in C++ 17 è ora molto più semplice:
struct Derived : Base {
using Base::Base;
/*
C++17:
Derived::Derived(int a, int b, int c = 1, int d = 2, int e = 3) : Base(a, b, c, d, e) {}
*/
};
Perché credo che questo sia:
Sulla base del cppreference.com page sui costruttori che ereditano e la carta che ha introdotto le modifiche (P0136R1), l'intero [class.inhctor]\1
sottosezione, che specificate come i costruttori ereditate vengono divisi e 'iniettato' nel la classe derivata è stata rimossa. (In effetti, l'intera sezione [class.inhctor]
è stata rimossa).E 'stato poi sostituito con una semplice regola in [namespace.udecl]\16
in C++ 17, che dice (sottolineatura mia):
Ai fini della risoluzione di sovraccarico, le funzioni che vengono introdotte da una dichiarazione using in un derivato Le classi vengono considerate come se fossero membri della classe derivata. In particolare, implicitamente questo parametro deve essere trattato come se fosse un puntatore alla classe derivata piuttosto che alla classe base. Ciò non ha alcun effetto su il tipo di funzione e, in tutti gli altri aspetti, la funzione rimane un membro della classe base. Analogamente, i costruttori introdotti da una dichiarazione di utilizzo vengono trattati come se fossero costruttori della classe derivata durante la ricerca dei costruttori della classe derivata (6.4.3.1) o della formazione di un gruppo di sovraccarico candidati (16.3 .1.3, 16.3.1.4, 16.3.1.7). Se viene selezionato un costruttore per eseguire l'inizializzazione di un oggetto di tipo classe, tutti i sottooggetti diversi dalla classe base da cui è stato originato il costruttore sono implicitamente inizializzati (15.6.3).
Quindi l'elenco dei parametri ora "trasporta" completamente. In effetti questa è la mia esperienza con CLion compatibile con P0136R1 con GCC 7.2, mentre il mio Visual Studio 2017 non compatibile con P0136R1 (15.6) mostrava i precedenti costruttori con gli argomenti predefiniti abbandonati.
Mi azzardo a supporre che, poiché i parametri predefiniti possono essere specificati solo una volta, una classe derivata non può ereditare tecnicamente un costruttore con parametri predefiniti, poiché il compilatore non saprebbe quale dei set di valori predefiniti utilizzare. –
Se ho capito bene, intendi che non ci dovrebbe essere una contraddizione tra le due definizioni. Ma qui nessuna contraddizione è possibile ... – AlwaysLearning
Mi azzarderei ad indovinare che facendo così eviti di fare copie extra quando passi quei parametri inizializzati con argomento predefinito a un costruttore di una classe base –