Namespaces
Variants

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

From cppreference.net
Iterator library
Iterator concepts
Iterator primitives
input_iterator_tag output_iterator_tag forward_iterator_tag bidirectional_iterator_tag random_access_iterator_tag contiguous_iterator_tag
(C++20)
Algorithm concepts and utilities
Indirect callable concepts
Common algorithm requirements
(C++20)
(C++20)
(C++20)
Utilities
(C++20)
Iterator adaptors
Range access
(C++11) (C++14)
(C++14) (C++14)
(C++11) (C++14)
(C++14) (C++14)
(C++17) (C++20)
(C++17)
(C++17)
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.

  1. input_iterator_tag entspricht LegacyInputIterator .
  2. output_iterator_tag entspricht LegacyOutputIterator .
  3. forward_iterator_tag entspricht LegacyForwardIterator .
  4. bidirectional_iterator_tag entspricht LegacyBidirectionalIterator .
  5. random_access_iterator_tag entspricht 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 input_iterator -Typ It kann entweder It :: iterator_concept (falls std:: iterator_traits < It > von der primären Template generiert wird) oder std:: iterator_traits < It > :: iterator_concept (falls std:: iterator_traits < It > spezialisiert ist) als Alias für einen dieser Tags deklariert werden, um das stärkste Iterator-Konzept anzugeben, das It zu modellieren beabsichtigt.

  1. input_iterator_tag entspricht input_iterator .
  2. forward_iterator_tag entspricht forward_iterator .
  3. bidirectional_iterator_tag entspricht bidirectional_iterator .
  4. random_access_iterator_tag entspricht random_access_iterator .
  5. contiguous_iterator_tag entspricht contiguous_iterator .

Falls iterator_concept nicht bereitgestellt wird, wird iterator_category als Fallback verwendet. Falls iterator_category ebenfalls nicht bereitgestellt wird (d.h. It ist kein LegacyIterator ), und std:: iterator_traits < It > nicht spezialisiert ist, wird random_access_iterator_tag angenommen.

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)