es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Iterador de C++ para listas enlazadas de C: para utilizar bucles for basados en rango.

Estoy trabajando con código heredado en C y el nuevo código está escrito en C++. Para usar la biblioteca estándar de C++, escribí un sencillo Iterador para la LinkedList heredada, como se muestra a continuación después de leer la publicación del blog de Bjarne Stroustrup sobre Adaptación.

Mi pregunta es:

  1. Quiero crear otro Iterador para otra estructura llamada TokenList. No estoy seguro de cómo usar el espacio de nombres y aún así poder utilizar los bucles for basados en rango. Cualquier ayuda sería útil.

  2. ¿Son correctos los adaptadores para el Iterador, es decir, begin, end, ++, *, !=? Actualmente, estoy interesado en leer el contenido de LinkedList utilizando bucles for basados en rango.

Coliru: enlace

“`lang-cpp
#include <cstdio>
#include <numeric>
#include <algorithm>

struct LinkedList {
double v;
LinkedList *next;
};

struct Iterator {
LinkedList *current;
LinkedList &c;
};

Iterator begin(LinkedList c) { return Iterator {c, *c}; }
Iterator end(LinkedList *c) { return Iterator {nullptr, *c}; }
Iterator &operator++(Iterator &p) { p.current = p.current->next; return p; }
LinkedList *operator()(Iterator p) { return p.current; }
bool operator!=(Iterator lhs, Iterator rhs) { return (lhs.current != rhs.current); }

int main()
{
LinkedList *node1 = new LinkedList;
LinkedList *node2 = new LinkedList;
LinkedList *node3 = new LinkedList;

<pre><code>node1->v = 1; node1->next = node2;
node2->v = 2; node2->next = node3;
node3->v = 3; node3->next = nullptr;

printf("// Estilo C: iteración\n");
for (auto ptr = node1; ptr; ptr = ptr->next) {
printf("%e\n", ptr->v);
}

auto head = node1;
// hacer uso de begin(), end(), ++, != y *
printf("// Estilo C++ moderno: bucle for basado en rango\n");
for (const auto& it : head) {
printf("%e\n", it->v);
}

delete node3;
delete node2;
delete node1;

return 0;
</code></pre>

}
“`

Tags:  ,

Answer

  1. Avatar for davy.ai
    1. Para crear otro Iterator para struct TokenList, puedes definir una nueva struct con las variables miembro y funciones adecuadas para iterar a través de TokenList. En cuanto al uso de namespace, simplemente puedes definir tu nuevo Iterator dentro de un namespace e importarlo al principio de tu archivo. De esta manera, puedes usar tu Iterator cualificado con el namespace en el bucle for basado en rangos sin conflictos. Aquí tienes un ejemplo:
    namespace TokenListIter {
        // Define tu Iterator aquí.
    }
    
    using TokenListIter::Iterator; // Importa el Iterator cualificado con el namespace.
    
    1. Los adaptadores para el Iterator parecen correctos, ya que proporcionan la funcionalidad necesaria para iterar a través de LinkedList. Sin embargo, es posible que desees considerar sobrecargar el operador -> para permitir un acceso más fácil a la variable miembro v de cada nodo de LinkedList en el bucle for basado en rangos. Aquí tienes un ejemplo de definición de la sobrecarga del operador ->:
    LinkedList* operator->() { return current; }
    

    Con esta sobrecarga, puedes usar el operador -> en lugar del operador de desreferencia * para acceder a la variable miembro v en el bucle for basado en rangos:

    for (const auto& it : head) {
        printf("%e\n", it->v);
    }
    

Comments are closed.