c++ iterator c++17 iterator-traits

c++ - Detección de iteradores contiguos



iterator c++17 (1)

La razón se da en N4284 , que es la versión adoptada de la propuesta de iteradores contiguos:

Este documento introduce el término "iterador contiguo" como un refinamiento del iterador de acceso aleatorio, sin introducir el correspondiente contiguous_iterator_tag , que se descubrió que rompe el código durante las discusiones de Issaquah en el documento de Nevin Liber N3884 "Iteradores contiguos: un refinamiento de iteradores de acceso aleatorio" .

Se rompió algo de código porque asumió que std::random_access_iterator no se pudo refinar, y tenía comprobaciones explícitas contra él. Básicamente, rompió el código incorrecto que no dependía del polimorfismo para verificar las categorías de iteradores, pero no obstante, rompió el código, por lo que se eliminó de la propuesta contiguous_iterator_tag .

Además, hubo un problema adicional con las clases de tipo std::reverse_iterator : un iterador contiguo invertido no puede ser un iterador contiguo, sino un iterador de acceso aleatorio regular. Este problema podría haberse resuelto para std::reverse_iterator , pero más envoltorios de iteradores definidos por el usuario que aumentan un iterador al copiar su categoría de iteradores habrían mentido o dejado de funcionar correctamente (por ejemplo, los adaptadores de iteradores de Boost).

En una nota al margen, hay planes para recuperar un equivalente de std::contiguous_iterator_tag con algunas soluciones para que funcione con la integración de Ranges TS en C ++ 20.

C ++ 17 introdujo el concepto de ContiguousIterator http://en.cppreference.com/w/cpp/iterator . Sin embargo, no parece que haya planes para tener un contiguous_iterator_tag (de la misma manera que ahora tenemos random_access_iterator_tag ) reportado por std::iterator_traits<It>::iterator_category .

¿Por qué falta contiguous_iterator_tag ?

¿Existe un protocolo convencional para determinar si un iterador es contiguo? ¿O una prueba de compilación?

Anteriormente mencioné que para los contenedores, si hay un miembro .data() que se convierte en un puntero a tipo de ::value y hay un miembro .size() convertible en diferencias de puntero, entonces se debe asumir que el contenedor es contiguo. pero no puedo sacar una característica análoga de los iteradores.

Una solución podría ser tener también una función de data para iteradores contiguos.

Por supuesto, el concepto contiguo funciona si &(it[n]) == (&(*it)) + n , para todo n , pero esto no puede verificarse en el momento de la compilación.

EDITAR : Encontré este video que lo coloca en el contexto más amplio de los conceptos de C ++. CppCon 2016: "Construyendo y extendiendo la jerarquía de iteradores en un mundo moderno y multinúcleo" por Patrick Niedzielski. La solución utiliza conceptos (Lite), pero al final la idea es que los iteradores contiguos deben implementar una función pointer_from (igual que la función de mis data(...) ).

La conclusión es que los conceptos ayudarán a formalizar la teoría, pero no son mágicos, en el sentido de que alguien, en algún lugar, definirá nuevas funciones especialmente nombradas sobre iteradores que son contiguos. La charla se generaliza a los iteradores segmentados (con las correspondientes funciones de segment y local ), por desgracia no dice nada acerca de los punteros de zancada.