Espacios de nombres
Variantes

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

De cppreference.com
 
 
Biblioteca de iteradores
Conceptos de iteradores
Primitivas de iteradores
Conceptos de algoritmos y servicios
Conceptos invocables indirectos
Requerimientos comunes de algoritmos
Servicios
Adaptadores de iteradores
Iteradores de flujos
Puntos de personalización de iteradores
Operaciones de iteradores
(C++11)
(C++11)
Acceso a rangos
(C++11)(C++14)
(C++11)(C++14)
(C++17)(C++20)
(C++14)(C++14)
(C++14)(C++14)
(C++17)
(C++17)
 
<tbody> </tbody>
Definido en el archivo de 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.

Categoría de iterador

Para cada tipo It de IteradorLegado, se debe definir un typedef std::iterator_traits<It>::iterator_category que sea un alias de 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 IteradorDeEntradaLegado.
  2. output_iterator_tag corresponde a IteradorDeSalidaLegado.
  3. forward_iterator_tag corresponde a IteradorDeAvanceLegado.
  4. bidirectional_iterator_tag corresponde a IteradorBidireccionalLegado.
  5. random_access_iterator_tag corresponde a IteradorDeAccesoAleatorioLegado.

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

Concepto de iterador

Para cada input_iterator de tipo It, se puede declarar It::iterator_concept (si std::iterator_traits<It> se genera a partir de la plantilla principal) o std::iterator_traits<It>::iterator_concept (si std::iterator_traits<It> está especializado) como un alias para una de estas etiquetas, para indicar el concepto de iterador más sólido 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 no se proporciona iterator_concept, se utiliza iterator_category como alternativa. Si tampoco se proporciona iterator_category (es decir, It no es un Iterator) y std::iterator_traits<It> no está especializado, se supone random_access_iterator_tag.

En cualquier caso, no se satisface ningún concepto si no se admiten las operaciones requeridas, independientemente de la etiqueta.

(desde C++20)

Notas

No existe una etiqueta independiente para IteradorContiguoLegado. Es decir, no es posible identificar un IteradorContiguoLegado en función de su iterator_category. Para definir un algoritmo especializado para iteradores contiguos, utiliza el concepto contiguous_iterator. (desde C++20)

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

Ejemplo

La técnica común para la selección de algoritmos basada en etiquetas de categoría de iterador es utilizar una función despachadora (la alternativa es std::enable_if). Las clases de etiqueta de iterador también se utilizan en las definiciones de conceptos correspondientes para indicar los requisitos, que no se pueden expresar solo en términos de patrones de uso. (desde C++20)

#include <iostream>
#include <iterator>
#include <list>
#include <vector>

// Usando conceptos (comprobación de etiqueta es parte de los mismos conceptos)

template<std::bidirectional_iterator BDIter>
void alg(BDIter, BDIter)
{
    std::cout << "1. alg() \t llamado para iterador bidireccional\n";
}

template<std::random_access_iterator RAIter>
void alg(RAIter, RAIter)
{
    std::cout << "2. alg() \t llamado para iterador de acceso aleatorio\n";
}

// Legado, usando despacho de etiqueta

namespace legado
{
    // Muy a menudo, los detalles de implementación están ocultos en un
    // espacio de nombres dedicado.
    namespace detalles
    {
        template<class BDIter>
        void alg(BDIter, BDIter, std::bidirectional_iterator_tag)
        {
            std::cout << "3. legado::alg() llamado para iterador bidireccional\n";
        }

        template<class RAIter>
        void alg(RAIter, RAIter, std::random_access_iterator_tag)
        {
            std::cout << "4. legado::alg() llamado para iterador de acceso aleatorio\n";
        }
    } // namespace detalles

    template<class Iter>
    void alg(Iter first, Iter last)
    {
        detalles::alg(first, last,
            typename std::iterator_traits<Iter>::iterator_category());
    }
} // namespace legado

int main()
{
    std::list<int> l;
    alg(l.begin(), l.end()); // 1.
    legado::alg(l.begin(), l.end()); // 3.

    std::vector<int> v;
    alg(v.begin(), v.end()); // 2.
    legado::alg(v.begin(), v.end()); // 4.

//  std::istreambuf_iterator<char> i1(std::cin), i2;
//  alg(i1, i2);         // Error de compilación: 
                         //no hay ninguna función coincidente para la llamada
//  legado::alg(i1, i2); // Error de compilación:
                         //no hay ninguna función coincidente para la llamada
}

Salida:

1. alg() 	 llamado para iterador bidireccional
3. legado::alg() llamado para iterador bidireccional
2. alg() 	 llamado para iterador de acceso aleatorio
4. legado::alg() llamado para iterador de acceso aleatorio

Véase también

El iterador básico.
(plantilla de clase) [editar]
Proporciona una interfaz uniforme para las propiedades de un iterador.
(plantilla de clase) [editar]