2009-11-03 15 views

Respuesta

16

Agregar solo funcionará con iteradores de acceso aleatorio. std :: advance funcionará con todo tipo de iteradores. Siempre que solo maneje iteradores en vectores, no hay diferencia real, pero std :: advance mantiene su código más genérico (por ejemplo, podría sustituir una lista para el vector, y esa parte aún funcionaría).

Editar: Para los que se preocupan, la norma describe advance y distance de la siguiente manera (§24.3.4/1):

Dado que sólo los iteradores de acceso aleatorio proporcionan los operadores + y -, la biblioteca proporciona dos funciones plantillas advance y distance. Estas plantillas de función usan + y - para iteradores de acceso aleatorio (y son, por lo tanto, tiempo constante para ellos); para los iteradores de entrada, reenvío y bidireccionales usan ++ para proporcionar implementaciones de tiempo lineal.

+12

Por otro lado, el uso de menos código genérico le impedirá código involuntariamente pessimizing: después de todo no podría ser una buena idea para hacer un montón de "acceso aleatorio" con un contenedor de lista. – UncleBens

0

Depende del iterador. it=it+5 es más rápido si es compatible (solo es compatible con iteradores de acceso aleatorio). Si desea avanzar un iterador menos capaz (por ejemplo, un iterador directo o un iterador bidireccional), puede usar std::advance, pero es más lento porque en realidad recorre todos los elementos intermedios.

+1

Te equivocas, el estándar dicta que std :: advance es lineal para las secuencias de acceso aleatorio: "Complejidad: Tiempo constante si InputIterator es un modelo de iterador de acceso aleatorio; de lo contrario, tiempo lineal." – Blindy

+1

std :: advance es tiempo constante para iteradores de acceso aleatorio (§24.3.4/1). –

+0

No creo que sea cierto para los iteradores de acceso aleatorio - std :: advance debe ser tan eficiente como el operador + en ese caso. – Kylotan

0

std::advance funciona también en iteradores no aleatorios, mientras que la versión += funciona en secuencias de acceso aleatorio (vectores y similares).

0

std::adnvance es genérico - es útil si no siempre conoce el tipo de contenedor subyacente - funciona en todos los casos.

Sin embargo, es eficiente: std::advance va a hacer una optimización si se aprobó una RandomAccessIterator (como uno de std::vector) y aumentará de iteración de bucle para ForwardAccessIterator (como como uno de std::list).

0

Usar std :: advance. Es igual de eficiente (utiliza rasgos de iterador para simplemente agregar iteradores para los iteradores de acceso aleatorio), y es más general porque también funciona en otros tipos de iteradores.

7

Eso depende de lo que necesita:

Si necesita genericity, utilice std::advance(it,2). Si alguien viene y cambia su std::vector en un std::list, el código aún se compilará, aunque avanzar ahora lleva tiempo lineal en lugar de tiempo constante.

Si necesita rendimiento, utilice it+=2. Si alguien viene y cambia su std::vector en un std::list, el código no podrá compilarse, señalando (tal vez con un comentario útil) a un problema de rendimiento grave.

0

Si nunca vas a cambiar el recipiente (y es probable que no lo son), utilice + porque es fácil de ver y entender el código y deja menos desordenada.

Si usted piensa que desea cambiar el recipiente, o si se está trabajando dentro de una plantilla que podrían ser instanciado en varios tipos de contenedores, la utilización anticipada, ya que funciona con cualquier cosa.

Como regla general, no me preocupa cambiar los tipos de contenedores porque he encontrado que cuando tengo que cambiar un tipo de contenedor, termino revisitando en todas partes ese contenedor, de todos modos, para asegurarme de que No estoy haciendo nada que de repente sea estúpido (como arrancar elementos aleatoriamente de la mitad de una lista).