Hier ein paar Jahre später, wo C ++ 11 und C ++ 14 es viel einfacher machen, solche Dinge zu tun. Ein Iterator ist in seinem Kern etwas, das dereferenzierbar und inkrementierbar ist. Wenn es ein Eingabe-Iterator ist, dann auch vergleichbar. Lassen Sie uns mit letzterem gehen - da sieht das aus, was Sie wollen.
Die einfachste Version wäre void_t
:
Basisfall:
%Vor%Gültige Spezialisierung:
%Vor%Alias:
%Vor% Sie müssen sich nicht auf iterator_category
verlassen oder die langweilige C ++ 03-Art der Überprüfung verwenden, indem Sie die Überladungsauflösung verwenden. Ausdruck SFINAE ist, wo es ist.
Wie Mr. Wakely in den Kommentaren betont, erfordert [iterator.traits] Folgendes:
es ist erforderlich, dass
%Vor%Iterator
der Typ von ist ein Iterator, die Typenwird als Differenztyp, Werttyp und Iteratorkategorie des Iterators definiert.
So können wir unser Iteratormerkmal definieren, um einfach nach dem zu suchen:
%Vor% Wenn iterator_traits<T>::iterator_category
schlecht formatiert ist, dann ist T
kein Iterator.
Nun, Sie könnten prüfen, ob der Typ einen verschachtelten Typdef namens iterator_category
hat. Dies kann mit SFINAE
geschehen, und die genaue Technik kann in Wiki-Seite für SFINAE
. Dies ist keine 100% -Methode, aber alle vernünftigen Iteratoren sollten die allgemeinen typedefs für Iteratoren bereitstellen, und die iterator_category ist eine, die für Iteratoren einzigartig ist. Vergessen Sie auch nicht zu überprüfen, ob TYPE einfach ein Zeiger ist. Zeiger sind Iteratoren.
Das ursprüngliche Poster stellte klar, dass sie tatsächlich nach einem Weg zur Identifizierung eines InputIterators fragen (siehe Ссылка ) ) weil sie den Iterator inkrementieren und dereferenzieren wollen. Dies hat eine sehr einfache SFINAE-Lösung in Standard C ++ 11, z. ähnlich wie bei der gcc STL:
%Vor%Dies beruht auf den Trace-Klassen des Iteratortyps, die die Typdefinitionen definieren, die nach Ansicht von Armen Tsirunyan von den Iteratoren selbst benötigt wurden. (Die Iteratoren können diese typedefs bereitstellen, aber sie können sie auch in Merkmalsklassen bereitstellen, was notwendig ist, um nackte Zeiger als Iteratoren zu verwenden, und dazu sind die Standardbibliotheksimplementierungen erforderlich.)