Extending vector iterator to fill my needs
I have the following design in one of my projects:
template<typename C> class B {
int numValue;
C inner;
}
template<typename C> class A {
vector<B<C>> c开发者_运维百科ontainer;
...
Iterator InsertItem(C item) {...}
}
What I want is a way to modify the existing vector iterator to return an Iterator which will return &inner on dereferencing instead of returning a reference to a B object. Hope it doesn't need a complete iterator class implementation.
Such an iterator is Boost.TransformIterator
Example (filling in your code, not that it is particularly good design).
#include <vector>
#include <iostream>
#include <functional>
#include <boost/iterator/transform_iterator.hpp>
using namespace std;
template<typename C> struct B {
int numValue;
C inner;
};
template <class T>
struct get_inner: std::unary_function<B<T>&, T&>
{
T& operator()(B<T>& value) const { return value.inner; }
};
template<typename C> struct A {
vector<B<C> > container;
typedef boost::transform_iterator<get_inner<C>, typename vector<B<C> >::iterator> Iterator;
Iterator InsertItem(C item) {
B<C> b = {0, item};
container.push_back(b);
return Iterator(--container.end());
}
};
int main()
{
A<double> a;
A<double>::Iterator it = a.InsertItem(3.14);
std::cout << *it << '\n';
}
I don't see where you need to modify an iterator at all. Rather, you just need to add a few member functions to B that return appropriate iterators to inner:
template <class C>
class B {
C inner;
public:
typedef typename C::iterator iterator;
typedef typename C::const_iterator const_iterator;
// etc.
iterator begin() { return inner.begin(); }
iterator end() { return inner.end(); }
// and so on for rbegin, rend, cbegin, cend, ...
};
Edit: I should add that if you want to support (for one example) back_insert_iterator
, you'll also need to add a push_back
to B, which you'll also (probably) implement by having it forward to C::push_back
.
If your iterator returns &inner
, how will you ever access numValue
?
If you create your own A::iterator, it should be easy to have it contain a vector<B<C>>::iterator
and forward most operations through it. Yes you'll need a full iterator class implementation, but it won't be difficult at all.
Use boost::transform_iterator
to create a new iterator that wraps your vector iterator, but yields the inner
value instead:
template<typename C>
C& getInner(B<C>& b)
{
return b.inner;
}
vector<B<C>> container;
typedef boost::transform_iterator<C&(*)(B<C>&), vector<B<C> >::iterator> inner_iterator;
inner_iterator it=boost::make_transform_iterator(container.begin(), getInner<C>)
精彩评论