Considere la siguiente secuencia:¿Cómo puedo escribir un contenedor de iteradores que combine grupos de valores secuenciales del iterador subyacente?
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
tengo iteradores de entrada para esa secuencia. Quiero envolver los iteradores de iteradores que producen la secuencia siguiente en su lugar:
(1,2), (3,4), (5,6), (7,8), (9,10)
Si no está claro, esta secuencia es una secuencia de pares consecutivos de elementos consecutivos de la original. Mientras que el original tiene 10 elementos, este tiene 5: cada uno se obtiene de dos de la secuencia original.
estoy usando Boost iterator_facade
para implementar esto, y tengo este intento equivocado en esto:
template <typename Iterator>
struct pairing_iterator
: boost::iterator_facade<
pairing_iterator<Iterator>,
std::array<typename std::iterator_traits<Iterator>::value_type, 2>,
std::input_iterator_category
// I should probably customize reference too, but it's not relevant
> {
pairing_iterator(Iterator it) : it(it) {
increment(); // A
}
pairing_iterator::value_type dereference() const {
return pair;
}
bool equal(pairing_iterator const& that) const {
return it == that.it; // B
}
void increment() {
pair = { { *it++, *it++ } };
}
Iterator it;
pairing_iterator::value_type pair;
};
Uno de los problemas que estoy enfrentando es en la línea marcada con A: cuando el iterador es aprobada en un iterador final, esto dará como resultado incrementarlo, lo que no puedo hacer.
Otro está en la línea marcada con B: estoy manteniendo el iterador subyacente siempre por delante del par "actual", por lo que si el iterador está en el último par, el iterador subyacente será un iterador final, y por lo tanto compare verdadero contra un final pairing_iterator.
Si el iterador subyacente era iterador directo, simplemente podría leer el par cada vez que desreferencia, y simplemente avanzar dos veces al incrementar. Pero con iteradores de entrada solo puedo leer una vez.
¿Estoy reinventando una rueda que ya existe en alguna parte? No encontré nada como esto en Boost, lo que me sorprende un poco. Pero me encantaría encontrar una solución ya hecha.
Si esta rueda ya no existe, ¿cómo puedo hacer que ruede realmente?
En mi opinión, esto es similar a un iterador de filtrado. Yo diría que es mejor que el iterador contenga el iterador final, para manejar el caso en el que la secuencia contiene inesperadamente un número impar de elementos. Esto también resolvería sus dos problemas (A y B), ya que sabe si es un iterador final, y puede separar la realización del par de proxy del incremento del iterador subyacente. (No estoy tan familiarizado con la fachada del iterador de Boost, así que no estoy del todo seguro de cómo traducir esto a Boosteese). –
'Desreferencia de enteros()'? –
@David oops, eso fue un artefacto de mí 'comprar detalles innecesarios lejos del ejemplo :) –