template <class T>
class VectorIterator
{
private:
typename T::iterator mCurrent;
typename T::iterator mEnd;
VectorIterator() {};
public:
typedef typename T::value_type ValueType;
VectorIterator(typename T::iterator start, typename T::iterator end)
: mCurrent(start), mEnd(end)
{
}
explicit VectorIterator(T& c)
: mCurrent(c.begin()), mEnd(c.end())
{
}
bool hasMoreElements(void) const
{
return mCurrent != mEnd;
}
typename T::value_type getNext(void)
{
return *mCurrent++;
}
};
Все прекрасно, за исключением того что по такому чуду инженерной мысли не естественно не будет работать BOOST_FOREACH, что явно не удобно и не привычно. Официальные доки Boost для решения подобных вопросов предлагают нам 2 возможных выхода:
- Предоставить typdef на iterator и const_iterator и вытащить наружу begin и end.
- Специализировать range_begin,range_end etc
Комбинируя оба варианта и используя friend можно предоставить пользователю доступ к BOOST_FOREACH и в тоже время спрятать от него настоящие итераторы...
template<typename T> class CollectionWrapper
{
public:
typedef typename T::iterator iterator;
typedef typename T::const_iterator const_iterator;
CollectionWrapper(T& collection):begin(collection.begin()),end(collection.end()){}
private:
iterator begin;
iterator end;
CollectionWrapper(){}
friend iterator range_begin( CollectionWrapper<T> & x ){return x.begin;}
friend iterator range_end( CollectionWrapper<T> & x ) {return x.end;}
friend const_iterator range_begin( CollectionWrapper<T> const & x ){return x.begin;}
friend const_iterator range_end( CollectionWrapper<T> const & x ) {return x.end;}
};
И теперь можно пользоваться:
std::string str = "some string";
CollectionWrapper<std::string> s(str);
BOOST_FOREACH(char ch, s)
std::cout<<ch<<std::endl;
Комментариев нет:
Отправка комментария