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
| 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.
input_iterator_tagcorresponde a IteradorDeEntradaLegado.output_iterator_tagcorresponde a IteradorDeSalidaLegado.forward_iterator_tagcorresponde a IteradorDeAvanceLegado.bidirectional_iterator_tagcorresponde a IteradorBidireccionalLegado.random_access_iterator_tagcorresponde 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 iteradorPara cada
Si no se proporciona 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) | |
| Proporciona una interfaz uniforme para las propiedades de un iterador. (plantilla de clase) |