2010-11-04 14 views
5

vi el siguiente código se utiliza para eliminar un elemento seleccionado del std::vector:¿El iterador admite + operador?

vector<hgCoord>::iterator it; 
int iIndex = 0; 
    const int iSelected = 5; 
for(it = vecPoints.begin(); it != vecPoints.end(); ++it, ++iIndex) 
{ 
    if(iIndex == iSelected) 
    { 
     vecPoints.erase(it); 
     break; 
    } 
} 

Argumento que este código no es eficiente y debe ser escrito de la siguiente manera:

vector<hgCoord>::iterator it; 
int iIndex = 0; 
    const int iSelected = 5; // we assume the vector has more than 5 elements. 

    vecPoints.erase(vecPoints.begin() + iSelected); 

Sin embargo, no estoy Asegúrese de si este código sigue o no el estándar C++ STL.

+0

Tiene razón, ya que 'std :: vector :: iterator' es un' RandomAccessIterator' (a.k.a. 'T *'). Solo recuerda que si tienes menos de 5 elementos en tu vector, tu segundo algoritmo fallará. –

+1

Si esos prefix-'i''s son una forma de notación húngara, me opongo a cualquier parte del código. –

+0

@ eq-: qué, porque 'i' debe usarse como prefijo que significa' iterador', quiere decir ;-p –

Respuesta

12

para hacer de este código genérico, por lo que funciona sin importar si el repetidor apoya operator +, y utiliza la aplicación más eficaz disponible:

template <typename C> 
void erase_at(C& container, typename C::size_type index) { 
    typename C::iterator i = container.begin(); 
    std::advance(i, index); 
    container.erase(i); 
} 

Internamente, std::advance utiliza operator + si el tipo de iterador lo soporta. De lo contrario (por ejemplo, para std::list<>::iterator) avanza el iterador paso a paso en un bucle, al igual que el primer código que publicó.

+0

......... yup ..... +1 –

+3

En respuesta a un comentario sobre la respuesta eliminada de los dirbeas, creo que el motivo 'std :: advance' modifica su argumento, tiene que ver con el hecho porque es muy agnóstico, en particular funciona en todos los InputIterators, que son * baratos * pero * peligrosos * para copiar. Cuando se usa con un iterador que podría ser solo un InputIterator, no un ForwardIterator, no puede usar el viejo valor de forma segura nunca más, por lo que incluso si devolviera un iterador, solo lo usaría como 'i = std :: advance (i, n); ', o en un código temporal como en dribeas '. Devolver 'vacío' ayuda a prevenir la estupidez. A veces. Tal vez. –

+0

Gracias por esta explicación. – q0987

10

Los iteradores de acceso aleatorio admiten sumas y restas, y los iteradores std::vector tienen acceso aleatorio.

2

Usted argumentan correctamente :)

1

que debería funcionar bien para un vector porque iteradores vectoriales son iteradores de acceso aleatorio, por lo que está bien para añadir un offset como lo han hecho. Lo mismo no funcionará para algunos otros tipos de contenedores (como deque o mapa).

Por lo tanto, su código es mejor para un vector, pero el otro código puede haber sido diseñado para funcionar con otros tipos de contenedor.

+0

En realidad, 'deque' también usa iteradores de acceso aleatorio. –

+0

Creo que el código modificado funciona para vector, cadena y deque. – q0987

+0

@Fred Larson: ¡Ups! No sé por qué escribí deque, ¡me refiero a la lista! Gracias por la corrección. – dajames

Cuestiones relacionadas