vectors librerias libreria iterador estandar ejemplos ejemplo dev c++ iterator standards deprecated c++17

c++ - librerias - Preparación para std:: iterator en desuso



vector stl c++ ejemplos (2)

La opción 3 es una versión estrictamente más tipada de la opción 1, ya que debe escribir todos los mismos typedefs pero además envolver iterator_traits<X> .

La opción 2 es inviable como solución. Puede deducir algunos tipos (por ejemplo, la reference es simplemente decltype(*it) ), pero no puede deducir iterator_category . No puede diferenciar entre input_iterator_tag y forward_iterator_tag simplemente por la presencia de operaciones, ya que no puede verificar reflexivamente si el iterador cumple con la garantía multipass. Además, no se puede distinguir realmente entre esos y output_iterator_tag si el iterador produce una referencia mutable. Tendrán que proporcionarse explícitamente en alguna parte.

Eso deja la Opción 1. Supongo que deberíamos acostumbrarnos a escribir toda la repetitiva. Yo, por mi parte, doy la bienvenida a nuestros nuevos señores del túnel carpiano.

El 21 de marzo, el comité de normas votó para aprobar el desuso de std::iterator P0174 propuesto en P0174 :

La larga secuencia de argumentos nulos es mucho menos clara para el lector que simplemente proporcionar los typedef s esperados en la propia definición de clase, que es el enfoque adoptado por el borrador de trabajo actual, siguiendo el patrón establecido en c ++ 14

Antes de la herencia c ++ 17 de std::iterator se alentaba a eliminar el tedio de la implementación repetitiva del iterador. Pero la desaprobación requerirá una de estas cosas:

  1. Una plantilla repetitiva ahora deberá incluir todos los typedef s requeridos
  2. Los algoritmos que funcionan con iteradores ahora necesitarán usar auto lugar de depender del iterador para declarar tipos
  3. Loki Astari ha sugerido que std::iterator_traits puede actualizarse para que funcione sin heredar de std::iterator

¿Puede alguien aclararme cuál de estas opciones debería esperar, ya que diseño iteradores personalizados con miras a la compatibilidad con c ++ 17 ?


Las alternativas discutidas son claras, pero creo que se necesita un código de ejemplo.

Dado que no habrá un sustituto de idioma y sin depender de boost o de su propia versión de la clase base de iterador, el siguiente código que usa std::iterator se fijará en el código debajo.

Con std::iterator

template<long FROM, long TO> class Range { public: // member typedefs provided through inheriting from std::iterator class iterator: public std::iterator< std::forward_iterator_tag, // iterator_category long, // value_type long, // difference_type const long*, // pointer const long& // reference >{ long num = FROM; public: iterator(long _num = 0) : num(_num) {} iterator& operator++() {num = TO >= FROM ? num + 1: num - 1; return *this;} iterator operator++(int) {iterator retval = *this; ++(*this); return retval;} bool operator==(iterator other) const {return num == other.num;} bool operator!=(iterator other) const {return !(*this == other);} long operator*() {return num;} }; iterator begin() {return FROM;} iterator end() {return TO >= FROM? TO+1 : TO-1;} };

(Código de std::iterator con permiso original del autor).

Sin std::iterator

template<long FROM, long TO> class Range { public: class iterator { long num = FROM; public: iterator(long _num = 0) : num(_num) {} iterator& operator++() {num = TO >= FROM ? num + 1: num - 1; return *this;} iterator operator++(int) {iterator retval = *this; ++(*this); return retval;} bool operator==(iterator other) const {return num == other.num;} bool operator!=(iterator other) const {return !(*this == other);} long operator*() {return num;} // iterator traits using difference_type = long; using value_type = long; using pointer = const long*; using reference = const long&; using iterator_category = std::forward_iterator_tag; }; iterator begin() {return FROM;} iterator end() {return TO >= FROM? TO+1 : TO-1;} };