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 es.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)
Definido en el encabezado <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) (desde C++20)

Define la categoría de un iterador. Cada etiqueta es un tipo vacío.

Contenidos

Categoría del iterador

Para cada tipo LegacyIterator It , un typedef std:: iterator_traits < It > :: iterator_category debe definirse como un alias a uno de estos tipos de etiqueta, para indicar la categoría más específica en la que se encuentra It .

  1. input_iterator_tag corresponde a LegacyInputIterator .
  2. output_iterator_tag corresponde a LegacyOutputIterator .
  3. forward_iterator_tag corresponde a LegacyForwardIterator .
  4. bidirectional_iterator_tag corresponde a LegacyBidirectionalIterator .
  5. random_access_iterator_tag corresponde a LegacyRandomAccessIterator .

Las etiquetas de categoría de iterador contienen información que puede utilizarse para seleccionar los algoritmos más eficientes para el conjunto de requisitos específicos que implica la categoría.

Concepto de iterador

Para cada tipo input_iterator It , ya sea It :: iterator_concept (si std:: iterator_traits < It > se genera desde la plantilla principal) o std:: iterator_traits < It > :: iterator_concept (si std:: iterator_traits < It > está especializado) puede declararse como un alias a una de estas etiquetas, para indicar el concepto de iterador más fuerte que It pretende modelar.

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

Si iterator_concept no se proporciona, iterator_category se utiliza como alternativa. Si iterator_category tampoco se proporciona (es decir, It no es un LegacyIterator ), y std:: iterator_traits < It > no está especializado, se asume random_access_iterator_tag .

En cualquier caso, cada concepto no se satisface si las operaciones requeridas no están soportadas, independientemente de la etiqueta.

(desde C++20)

Notas

No existe una etiqueta separada para LegacyContiguousIterator . Es decir, no es posible identificar un LegacyContiguousIterator basándose en su iterator_category . Para definir algoritmos especializados para iteradores contiguos, utilice el contiguous_iterator concepto. (desde C++20)

No existen correspondencias entre output_iterator_tag y el concepto output_iterator . Establecer iterator_concept como output_iterator_tag solo indica que el tipo no modela input_iterator .

Ejemplo

Una técnica común para la selección de algoritmos basada en etiquetas de categoría de iteradores es usar una función despachadora (la alternativa es std::enable_if ). Las clases de etiquetas de iteradores también se utilizan en las definiciones de conceptos correspondientes para denotar los requisitos, que no pueden expresarse únicamente en términos de patrones de uso. (desde 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
}

Salida:

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

Véase también

(obsoleto en C++17)
clase base para facilitar la definición de tipos requeridos para iteradores simples
(plantilla de clase)
proporciona una interfaz uniforme para las propiedades de un iterador
(plantilla de clase)