Здравствуйте, Valus, Вы писали:
V>>в том то и дело, что придется заводить версию с передачей самого контейнера.
V>>а вот так нельзя?
С помощью эпической силы — всё можно.
Единственная засада, которую нам нужно обойти — это инвалидация итераторов контейнера после его изменения. Лечится путём введения прокси.
template<class Cont>
class lazy_iterator
{
// ленивые данные
Cont* cont;
bool begin;
// для итератора последовательного доступа есть 2 выделенных позиции: начало и конец;
// для произвольного - можно указать смещение от начала или от конца (0 - начало, +n - от начала, -1 - конец, -n-1 - от конца)
bool loaded;
typename Cont::iterator it;
void force()
{
if(loaded) return;
it = begin ? cont->begin() : cont->end();
loaded = true;
}
public:
lazy_iterator(Cont* c, bool b) : cont(c), begin(b), loaded(false) {}
// далее, у всех операторов выполняем force
typename Cont::iterator operator->() const { force(); return it; }
typename Cont::reference_type operator*() const { force(); return *it; }
lazy_iterator& operator++() const { force(); return it; }
bool operator==(const lazy_iterator& rhs) const
{
if(!loaded && !rhs.loaded) return begin == rhs.begin;
force(); rhs.force();
return it == rhs.it;
}
};
template<class Cont> lazy_iterator<Cont> lazy_begin(Cont& c) { return lazy_iterator<Cont>(c,true ); }
template<class Cont> lazy_iterator<Cont> lazy_end (Cont& c) { return lazy_iterator<Cont>(c,false); }
.......
template<class Iter, class Inserter>
void your_function(Iter begin, Iter end, Inserter ins)
{
// запихиваем через output iterator - Inserter
for(int i=0; i<123; ++i) *ins++ = i;
// обрабатываем через forward iterator'ы
for_each(begin,end, do_something);
}
.......
your_function(lazy_begin(vec), lazy_end(vec), back_inserter(vec));
Это, разумеется, эскиз и большей частью изврат. Но если уж тебе так припёрло...