Konwersja const_iteratora na iterator
Pytanie: jak zamienić const_iterator na zwykły iterator? Sposobów jest co
najmniej kilka, jednak mi do gustu najbardziej przypadł pewien trik
wykorzystujący fakt, że wszystkie kontenery w bibliotece standardowej mają
zaimplementowaną metodę iterator erase(const_iterator, const_iterator)
. Jej
obecność jest zapisana w standardzie dla wszystkich kontenerów sekwencyjnych,
asocjacyjnych i nieuporządkowanych asocjacyjnych.
Trik polega na tym, aby do erase
, zwracającego nie-constowy iterator,
przekazać żądanie usunięcia pustego zbioru. Zwrócony iterator wskazuje na
element umieszczony za ostatnim usuniętym elementem, czyli de facto na
poddawany konwersji iterator. Dodatkową zaletą tego rozwiązania jest to, że
konwersja następuje tu zazwyczaj w czasie stałym lub logarytmicznym. Jest to
krok naprzód w stosunku do naiwnych metod inkrementacyjnych, które zapewniają
jedynie złożoność liniową.
template <typename Container, typename ConstIterator>
Container::iterator convertToIterator(Container& c, ConstIterator it)
{
return c.erase(it, it);
}
Pierwotnym autorem powyższego rozwiązania jest Jon Kalb.