2010-05-13 7 views
9

Me gustaría obtener el siguiente valor para el iterador STL list pero no implementa operator+, vector lo tiene. ¿Por qué y cómo puedo obtener el valor donde quiero?¿Por qué solo el iterador de acceso aleatorio implementa operador + en C++?

Creo que puedo hacer eso si llamo a operator++ varias veces, pero ¿no está un poco sucio?

Lo que quiero hacer es la siguiente:

list<int> l; 
...omitted... 
list<int>::iterator itr = l.begin() + 3; // but, list iterator does not have 
             // operator+ 

¿Cuál es la mejor solución para lo que quiero?

+2

(Casi) no relacionado: debe asegurarse de que es posible alcanzar esta posición; de lo contrario, invocará un comportamiento no definido. Aunque de 'list :: begin()' es fácil, en un caso más genérico, la única forma de saber (para no RandomAccessIterator) la distancia con 'list :: end()' es invocar 'std :: distancia' ... O (N) también. –

+0

Dos excelentes respuestas en este hilo. +1 a la comunidad! –

Respuesta

17

También puede usar std::next (y anterior) o los equivalentes proporcionados por Boost si no tiene acceso a C++ 11.

list<int>::iterator itr = std::next(l.begin(), 3); 

Justificación: std::advance es difícil de usar (funciona a través de efectos secundarios, no devolviendo una copia).

+2

Eso es bueno saber. Siempre me pregunté por qué 'std :: advance' funcionaba con efectos secundarios en lugar de funcionar. –

+1

@RSam: Siempre he supuesto que es porque 'std :: advance' está destinado a imitar ++ itr o operator + =, según corresponda. Los algoritmos iteradores generalmente se escriben en esos términos, por lo que ajustarlos tiene más sentido. –

+0

Si quiere una copia, debe crearla usted mismo. Este es un caso común en C++. – mschneider

37

que desea utilizar std::advance:

list<int>::iterator itr = l.begin(); 
std::advance(itr, 3); 

advance utilizará operator+ y completa en un tiempo constante si el iterador es de acceso aleatorio mientras que será bucle en operator++ y completa en el tiempo lineal si el iterador no es de acceso aleatorio .  

La razón de esto es para darle control sobre los requisitos de complejidad. Si le importa la complejidad de su operación, use operator+ y consiga un tiempo constante, pero esto solo se compila con iteradores de acceso aleatorio. Si no le importa la complejidad, use std::advance, que siempre funcionará, pero la complejidad variará según el iterador.

+3

+1 simple, claro y completo. – wilhelmtell

Cuestiones relacionadas