Der C ++ 17-Standard führt "Anleitungen zum Abziehen von Vorlagen" ein. Ich habe festgestellt, dass sie etwas mit dem Abzug neuer Vorlagenargumente für Konstruktoren zu tun haben, die in dieser Version des Standards eingeführt wurden, aber ich habe noch keine einfache Erklärung im FAQ-Stil gesehen, was sie sind und wofür sie sind.
Was sind Vorlagenabzugshandbücher in C ++ 17?
Warum (und wann) brauchen wir sie?
Wie erkläre ich sie?
Antworten:
Vorlagenabzugsleitfäden sind Muster, die einer Vorlagenklasse zugeordnet sind und dem Compiler mitteilen, wie eine Reihe von Konstruktorargumenten (und ihre Typen) in Vorlagenparameter für die Klasse übersetzt werden sollen.
Das einfachste Beispiel ist das von
std::vector
und sein Konstruktor, der ein Iteratorpaar verwendet.Der Compiler muss , um herauszufinden , was
vector<T>
‚sT
Art sein wird. Wir wissen, was die Antwort ist;T
sollte seintypename std::iterator_traits<Iterator>::value_type
. Aber wie können wir dem Compiler mitteilen, ohne tippen zu müssen?vector<typename std::iterator_traits<Iterator>::value_type>
?Sie verwenden einen Abzugsleitfaden:
Dies teilt dem Compiler mit, dass beim Aufrufen eines
vector
Konstruktors, der diesem Muster entspricht, dievector
Spezialisierung mithilfe des Codes rechts von abgeleitet wird->
.Sie benötigen Hilfslinien, wenn der Abzug des Typs von den Argumenten nicht auf dem Typ eines dieser Argumente basiert. Beim Initialisieren von a
vector
von wirdinitializer_list
explizit dasvector
's verwendetT
, sodass keine Anleitung erforderlich ist.Die linke Seite gibt nicht unbedingt einen tatsächlichen Konstruktor an. Wenn Sie die Ableitung von Vorlagenkonstruktoren für einen Typ verwenden, stimmt dies mit den Argumenten überein, die Sie für alle Abzugsleitfäden übergeben (tatsächliche Konstruktoren der primären Vorlage bieten implizite Hilfslinien). Wenn es eine Übereinstimmung gibt, wird diese verwendet, um zu bestimmen, welche Vorlagenargumente für den Typ bereitgestellt werden sollen.
Sobald dieser Abzug erfolgt ist und der Compiler die Vorlagenparameter für den Typ ermittelt hat, erfolgt die Initialisierung für das Objekt dieses Typs so, als ob nichts davon geschehen wäre. Das heißt, der ausgewählte Abzugsleitfaden muss nicht mit dem ausgewählten Konstruktor übereinstimmen .
Dies bedeutet auch, dass Sie Hilfslinien mit Aggregaten und Aggregatinitialisierung verwenden können:
Abzugsleitfäden werden daher nur verwendet, um den zu initialisierenden Typ herauszufinden. Sobald diese Feststellung getroffen wurde, funktioniert der eigentliche Initialisierungsprozess genauso wie zuvor.
quelle
vector v{first, last};
nicht das Richtige getan wird :(std::string{32,'*'}[0] == ' '
(für ASCII). Dies ist jedoch seit C ++ 11 der Fall.