wrap std::iterator in C++
I have a need to wrap a vector iterator, but don't like the idea to rewrite it from scratch. And I can't subclass it as far as vector iterator doesn't seem to be cross-platform. At least gnu and ibm ones look different.
What I want to do is the following:
class MyContainer {
vector<double> data;
vec开发者_高级运维tor<int> indices;
iterator
begin()
{ return my_iterator(data, indices.begin()); }
iterator
end()
{ return my_iterator(data, indices.end()); }
}
MyContainer cont;
Where indices vector contains integer positions within the data vector. Data is supposed to be much much bigger than the indices.
So I need an iterator that can go through the indices in any direction like a normal vector iterator does with the only exception: it must return a value of data vector when the value is going to be accessed. e.g.:
for(MyContainer::iterator it = cont.begin(); it != cont.end(); it++) {
cout << *it << endl; // values of data should appear here
}
Basically it should look like a normal collection for the std world. You can iterate it in whatever direction you want, you can sort it, run unique, find_if, etc...
any simple solution?
There's a great Boost library for defining custom iterators. You need to provide a class with a few methods:
i.dereference() Access the value referred to
i.equal(j) Compare for equality with j
i.increment() Advance by one position
i.decrement() Retreat by one position
i.advance(n) Advance by n positions
i.distance_to(j) Measure the distance to j
Then you get the rest from the iterator_facade.
Good luck!
This looks a lot like a permutation_iterator, one of the "built in" adapters from the Boost.Iterator Library
See this example (modified from the Boost docs) on codepad.
There's nothing in the standard C++ library, but you can probably get boost::iterator_adapter
to do what you want. A preliminary examination suggests you'll need to override iterator_adapter::dereference
and iterator_adapter::equal
.
template <typename _Scalar=double,
typename _Idx=int,
typename _Seq=std::vector<_Scalar>,
typename _IdxVector=std::vector<_Idx> >
class SelIter
: public boost::iterator_adaptor< SelIter<_Scalar, _Idx>,
typename _IdxVector::iterator, _Scalar >
{
public:
typedef boost::iterator_adaptor< SelIter, typename _IdxVector::iterator, _Scalar > Base;
SelIter(_Seq& scalars, _IdxVector& idxs);
SelIter(_Seq& scalars, typename _IdxVector::iterator pi);
typename Base::reference dereference() const;
bool equal(const SelIter& x) const;
private:
// ...
}
精彩评论