扩展矢量迭代器以满足我的需求

时间:2010-09-28 16:04:24

标签: c++ templates iterator

我的一个项目中有以下设计:

template<typename C> class B {
    int numValue;
    C inner;
}

template<typename C> class A {
    vector<B<C>> container;
    ...
    Iterator InsertItem(C item) {...}
}

我想要的是一种修改现有向量迭代器以返回Iterator的方法,该迭代器将在取消引用时返回&amp; inner ,而不是返回对B对象的引用。 希望它不需要完整的迭代器类实现。

4 个答案:

答案 0 :(得分:2)

这样的迭代器是Boost.TransformIterator

示例(填写代码,而不是特别好的设计)。

#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';
}

答案 1 :(得分:1)

我根本看不到你需要修改迭代器的位置。相反,您只需要向B添加一些成员函数,将适当的迭代器返回到内部:

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, ...
};

编辑:我应该补充一点,如果您想支持(例如)back_insert_iterator,您还需要向B添加push_back,您也可以(可能)实施将其转发到C::push_back

答案 2 :(得分:0)

如果您的迭代器返回&inner,您将如何访问numValue

如果您创建自己的A :: iterator,则应该很容易让它包含vector<B<C>>::iterator并通过它转发大多数操作。是的,你需要一个完整的迭代器类实现,但它并不困难。

答案 3 :(得分:0)

使用boost::transform_iterator创建一个包装矢量迭代器的新迭代器,但产生inner值:

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