std:: input_iterator_tag, std:: output_iterator_tag, std:: forward_iterator_tag, std:: bidirectional_iterator_tag, std:: random_access_iterator_tag, std:: contiguous_iterator_tag
|
Definiert im Header
<iterator>
|
||
|
struct
input_iterator_tag
{
}
;
|
(1) | |
|
struct
output_iterator_tag
{
}
;
|
(2) | |
|
struct
forward_iterator_tag
:
public
input_iterator_tag
{
}
;
|
(3) | |
|
struct
bidirectional_iterator_tag
:
public
forward_iterator_tag
{
}
;
|
(4) | |
|
struct
random_access_iterator_tag
:
public
bidirectional_iterator_tag
{
}
;
|
(5) | |
|
struct
contiguous_iterator_tag
:
public
random_access_iterator_tag
{
}
;
|
(6) | (seit C++20) |
Definiert die Kategorie eines Iterators. Jedes Tag ist ein leerer Typ.
Inhaltsverzeichnis |
Iteratorkategorie
Für jeden
LegacyIterator
-Typ
It
muss ein
typedef
std::
iterator_traits
<
It
>
::
iterator_category
definiert sein, das als Alias für einen dieser Tag-Typen dient, um die spezifischste Kategorie anzugeben, in der sich
It
befindet.
-
input_iterator_tagentspricht LegacyInputIterator . -
output_iterator_tagentspricht LegacyOutputIterator . -
forward_iterator_tagentspricht LegacyForwardIterator . -
bidirectional_iterator_tagentspricht LegacyBidirectionalIterator . -
random_access_iterator_tagentspricht LegacyRandomAccessIterator .
Iterator-Kategorie-Tags enthalten Informationen, die verwendet werden können, um die effizientesten Algorithmen für die spezifischen Anforderungen auszuwählen, die durch die Kategorie impliziert werden.
Iterator-Konzept
Für jeden
Falls
In jedem Fall wird jedes Konzept nicht erfüllt, wenn die erforderlichen Operationen nicht unterstützt werden, unabhängig vom Tag. |
(seit C++20) |
Hinweise
Es gibt kein separates Tag für
LegacyContiguousIterator
. Das heißt, es ist nicht möglich, einen
LegacyContiguousIterator
anhand seiner
iterator_category
zu erkennen.
Um spezialisierte Algorithmen für zusammenhängende Iteratoren zu definieren, verwenden Sie das
contiguous_iterator
Konzept.
(seit C++20)
Es bestehen keine Entsprechungen zwischen
output_iterator_tag
und dem
output_iterator
-Konzept. Das Setzen von
iterator_concept
auf
output_iterator_tag
zeigt lediglich an, dass der Typ nicht das
input_iterator
-Konzept modelliert.
Beispiel
Eine gängige Technik für die Algorithmusauswahl basierend auf Iterator-Kategorie-Tags ist die Verwendung einer Dispatcher-Funktion (die Alternative ist std::enable_if ). Die Iterator-Tag-Klassen werden auch in den entsprechenden Konzeptdefinitionen verwendet, um die Anforderungen zu kennzeichnen, die nicht allein durch Verwendungsmuster ausgedrückt werden können. (seit C++20)
#include <iostream> #include <iterator> #include <list> #include <vector> // Using concepts (tag checking is part of the concepts themselves) template<std::bidirectional_iterator BDIter> void alg(BDIter, BDIter) { std::cout << "1. alg() \t called for bidirectional iterator\n"; } template<std::random_access_iterator RAIter> void alg(RAIter, RAIter) { std::cout << "2. alg() \t called for random-access iterator\n"; } // Legacy, using tag dispatch namespace legacy { // Quite often implementation details are hidden in a dedicated namespace namespace implementation_details { template<class BDIter> void alg(BDIter, BDIter, std::bidirectional_iterator_tag) { std::cout << "3. legacy::alg() called for bidirectional iterator\n"; } template<class RAIter> void alg(RAIter, RAIter, std::random_access_iterator_tag) { std::cout << "4. legacy::alg() called for random-access iterator\n"; } } // namespace implementation_details template<class Iter> void alg(Iter first, Iter last) { implementation_details::alg(first, last, typename std::iterator_traits<Iter>::iterator_category()); } } // namespace legacy int main() { std::list<int> l; alg(l.begin(), l.end()); // 1. legacy::alg(l.begin(), l.end()); // 3. std::vector<int> v; alg(v.begin(), v.end()); // 2. legacy::alg(v.begin(), v.end()); // 4. // std::istreambuf_iterator<char> i1(std::cin), i2; // alg(i1, i2); // compile error: no matching function for call // legacy::alg(i1, i2); // compile error: no matching function for call }
Ausgabe:
1. alg() called for bidirectional iterator 3. legacy::alg() called for bidirectional iterator 2. alg() called for random-access iterator 4. legacy::alg() called for random-access iterator
Siehe auch
|
(in C++17 veraltet)
|
Basisklasse zur Vereinfachung der Definition erforderlicher Typen für einfache Iteratoren
(Klassentemplate) |
|
bietet einheitliche Schnittstelle für die Eigenschaften eines Iterators
(Klassentemplate) |