Если у вас нет контроля над интерфейсом vector<int>
, например, потому что это на самом деле std::vector<int>
, первое, что вы хотите сделать, это изменить способ получения пользовательских итераторов.То есть вместо написания
for (vector<int>::my_iterator it = v.my_begin(); it != v.my_ned(); ++it)
вы бы использовали
for (my_iterator it(my_begin(v)), end(my_end(v)); it != end; ++it)
Вы можете получить модифицированный интерфейс для пользовательского контейнера, но это большая рыба для жарки.Создание вашего входного итератора теперь, по сути, сводится к созданию подходящей обертки для базового итератора.Это может выглядеть примерно так:
template <typename InIt, Pred>
struct my_iterator {
typedef typename std::iterator_traits<InIt>::value_type value_type;
typedef typename std::iterator_traits<InIt>::difference_type difference_type;
typedef typename std::iterator_traits<InIt>::reference reference;
typedef typename std::iterator_traits<InIt>::pointer pointer;
my_iterator(InIt it, InIt end, Pred pred): it_(it), end_(end), pred_(pred) {}
bool operator== (my_iterator const& other) const { reutrn this->it_ == other.it_; }
bool operator!= (my_iterator const& other) const { return !(*this == other); }
reference operator*() { return *this->it_; }
pointer operator->() { return this->it_; }
my_iterator& operator++() {
this->it_ = std::find_if(this->it_, this->end_, this->pred_);
return *this;
}
my_iterator operator++(int)
{ my_iterator rc(*this); this->operator++(); return rc; }
private:
InIt it_, end_;
Pred pred_;
Функции my_begin()
и my_end()
будут создавать подходящий объект этого типа.Один из способов избежать написания этого - взглянуть на адаптеры итератора Boost: там должно быть что-то подходящее.