librerias - vector stl c++ ejemplos
Encontrar el propietario de un iterador STL (7)
Como se sugirió anteriormente, es mejor reescribir el código para que no necesite este comportamiento. Es lo mismo que sostener una moneda, pero no tienes idea de dónde viene, a menos que lo hayas anotado en un papel.
Si no puede volver a escribir el código, puede introducir un objeto de ajuste que contenga un puntero al contenedor y al propio iterador. ¿Para qué necesitas esto específicamente?
¿Hay alguna manera de que pueda encontrar el contenedor señalado por un iterador? Específicamente, quiero ser capaz de encontrar el std :: vector apuntado por un std :: vector :: iterator en particular para que pueda verificar el rango, sin tener que pasar referencias a ese vector.
Si (como sospecho) la respuesta es no, ¿por qué no?
editar: gracias por una serie de respuestas rápidas y (en gran medida) precisas. Evan Teran lo clava. No estaba pensando en la optimización en absoluto, pero ahora es obvio.
Un par de personas me preguntaron para qué quiero hacer esto. No es nada terriblemente importante. Tengo un objeto que se inicializa con un vector y un iterador apuntando al vector. Sería lindo y conveniente si pudiera inicializar el objeto solo con un iterador, porque entonces podría convertir vectores :: iteradores directamente a este objeto (esto suena extraño pero tiene sentido en el caso particular). Pero no es crucial en absoluto.
El STL no permite esto.
Los iteradores de Vecor, por ejemplo, pueden implementarse simplemente como un puntero. Y no hay una forma general de recuperar un objeto de un puntero que apunta a algunos datos que el objeto ha asignado.
En teoría, hay una manera si el iterador en cuestión es al menos un iterador directo. Puede verificar si su iterador es uno de los iteradores en [primero, último] para cada contenedor candidato. Como está utilizando un contenedor vectorial, tiene un iterador de acceso aleatorio, puede usar el operador inferior para hacer esta comprobación rápidamente.
Usted TIENE que conocer todos los vectores candidatos frente a los cuales verificar desde el principio, y esta no es una forma general de obtener el contenedor al que pertenece un iterador.
Sin embargo, puede definir una extensión de iteradores de acceso aleatorio decorando el iterador de acceso aleatorio con algo que contenga un puntero al vector de creación. Es probable que sea levemente poco elegante, ineficiente e inconveniente. Así que vea si puede reescribir el código para evitar esta necesidad primero.
No creo que haya un método expuesto para hacer eso. La razón es que ese no es el propósito del iterador. Por supuesto, no hay ninguna razón técnica por la que un iterador no pueda contener un puntero a su contenedor padre. Incluso si se implementa de tal manera que no requiere ese puntero, aún podría contenerlo.
Los iteradores están destinados a iterar sobre la colección, y como tales, proporcionan la interfaz necesaria para hacer eso y solo eso. Esto es buenos principios de programación orientada a objetos.
¿Puedo preguntar cuál es su caso de uso, que necesita saber el "rango" del contenedor con un iterador?
No hay forma de hacer que eso funcione. La razón es simple: Agregar un camino a los iteradores para obtener el contenedor al que apuntan es
- Inútil. Iteradores iteran sobre una colección. Como otros dijeron, solo eso, nada más.
- No es compatible con los requisitos del iterador. Recuerde que un puntero es un iterador de acceso aleatorio. Colocar un puntero de contenedor en el iterador no sería útil para los algoritmos, ya que pretenden ser genéricos, desacoplados de implementaciones de iterador específicas. Un puntero utilizado como un iterador no puede tener un puntero a la matriz de la que se tomó como miembro.
Usted dice que lo necesita para verificar el rango. Puede proporcionar un iterador final que apunta uno después de la última posición válida del iterador de un rango. Verifica si tu posición actual no está al final. Eso es todo lo que necesita hacer para verificar el rango.
No puede recuperar el contenedor de un iterador de forma general. Como un ejemplo de por qué, un puntero simple se puede usar como un iterador:
#include <algorithm>
#include <cstdio>
#include <cstring>
int
main(int argc, char *argv[])
{
const char s[] = "Hello, world!";
const char *begin = s;
const char *end = s + strlen(s);
std::for_each(begin, end, putchar);
return 0;
}
¿Cómo podría recuperar la cadena original de un puntero (si no está apuntando al comienzo de la cadena)?
Sin embargo, si necesita esta funcionalidad, siempre puede implementar su propio contenedor alrededor del iterador que almacena una referencia al contenedor.
Yo no lo creo. Si los iteradores tenían que mantener una referencia / puntero al propietario, entonces sería imposible que se optimizaran hasta un puntero liviano (lo que se puede hacer con contenedores que garanticen el almacenamiento contiguo como vectores, etc.).