Ich versuche, einen Iterator als Template-Parameter an eine Template-Methode zu übergeben, aber der Compiler beschwert sich:
%Vor%Der Code, der den Fehler verursacht, ist:
%Vor%Ich schätze, es gibt eine einfache Möglichkeit, dies zu erreichen, da die meisten Standard-Algorithmen den Typ vom Iterator ableiten können.
Der Grund dafür ist, dass das Formular T
in einem nicht-abgeleiteten Kontext ist:
Betrachten Sie einen einfacheren Fall, um zu verstehen, warum:
%Vor% Worauf sollte T
ableiten? Es ist unmöglich zu bestimmen. Sie müssten den Typ ... explizit als Assert<A>(5)
angeben.
Siehe auch Was ist ein nicht-kontextbezogener Kontext?
, da die meisten Std-Algorithmen den Typ vom Iterator ableiten können.
Das liegt daran, dass die Standardalgorithmen nur den Typ Iterator und nicht den Containertyp ableiten. Zum Beispiel std::find
ist nur:
Es gibt hier kein Konzept von "Container" - es ist nur der Iterator-Typ, der abgeleitet werden muss. Das ist Teil der Schönheit der Algorithmenbibliothek.
Wenn Sie also nur den Inhalt des Iterators ausgeben möchten, wäre die korrekte Funktion einfach:
%Vor% Wenn Sie Assert(myVec.cbegin())
aufrufen, wird Iterator
als std::vector<double>::const_iterator
abgeleitet, was genau das ist, was Sie wollen.
Die Standardalgorithmen sehen so aus:
%Vor% Wenn sie den Typ des Iterators benötigen, können sie typename std::iterator_traits<Iterator>::value_type
verwenden.
Was sie nicht tun, ist in irgendeiner Weise auf einen Container wie vector
zu verweisen. Nicht alle Iteratoren stammen aus Containern.
Das ist es - die Standardbibliothek parametrisiert nur den ganzen Typ des Iterators. Tatsächlich kann alles, was sich wie ein Iterator verhält, verwendet werden (das ist der Hauptgrund, warum Iteratoren sich wie Zeiger verhalten). Dies wird "Enteneingabe" genannt.
Was Sie zu tun versuchen (die Funktion nur auf die Typen zu beschränken, die explizite Iteratoren sind), das ist es, worum es bei C ++ 17-Konzepten geht.
Tags und Links c++ templates template-deduction