Создание итератора-адаптера Mar 11, 2008

Очень часто в коде С++ (и не обязательно производства “до рождества христова”) встречается предоставляют доступа к набору каких-либо объектов в следующем виде:

size_t GetItemCount();
value_type GetItem(size_t i);

Для использования стандартными алгоритмами такое представление неудобно, поскольку требует в лобовом варианте предварительного формирования промежуточного контейнера (sic!). Решение проблемы достаточно простое (с использованием boost):

class smart_iterator : public boost::iterator_facade<std::random_access_iterator_tag, value_type, size_t>
{
public:
    iterator(size_t i = 0) : index_(i) { }
// implementation
    public:
    reference dereference() const { return GetItem(index_); }
    void increment() { ++index_; }
    void decrement() { --index_; }
    bool equal(const iterator& iter) const { return index_ == iter.index_; }

private:
    size_t index_;
};

Теперь можно делать STL-подобные вызовы:

std::copy(smart_iterator(), iterator(GetItemCount()), ...);

Очевидно, что для написания итератора boost привлекать не обязательно, но при взгляде на тот объем кода, который нужно вбить, чтобы сделать правильный STL-compliant итератор, желание так делать без причины сильно уменьшается :-) А поскольку в наших проектах boost используется массово, то никаких новых зависимостей по заголовкам такой прием чаще всего уже не порождает.