开发者

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>)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜