【问题标题】:Writing wrappers around stl classes with iterators in c++在 C++ 中使用迭代器围绕 stl 类编写包装器
【发布时间】:2013-03-07 04:11:38
【问题描述】:

我正在尝试使用自己的迭代器围绕std::liststd::vector 编写包装类,以便我可以为这两个类及其迭代器编写超类。我当前的代码看起来基本上是这样的:

template <class T>
class MyCollection
{
//Not sure how to write this class.
public:
    class iterator
    {
        //Not sure how to write this class either
        //I think MyVector::iterator and MyList::iterator
        //should inherit from this class
    };
};

template<class T>
class MyVector : public MyCollection<T>
{
private:
    vector<T> data;
public:
    MyVector(int * start, int * end) : data(start, end) {}
    class iterator : vector<T>::iterator
    {
        iterator(typename vector<T>::iterator i) : vector<T>::iterator(i) {}
    };
    iterator begin() { return iterator(data.begin()); }
};

template<class T>
class MyList : public MyCollection<T>
{
private:
    list<T> data;
public:
    Mylist(int * start, int * end) : data(start, end) {}
    class iterator : list<T>::iterator
    {
        iterator(typename list<T>::iterator i) : list<T>::iterator(i) {}
    };
    iterator begin() { return iterator(data.begin()); }
};

我希望能够有一些代码来做到这一点:

int ints[] = {1,2,3,4,5};
MyList<int> l(ints, ints+5);
MyCollection<int> * c = &l;
MyCollection<int>::iterator i = c->begin();

在该代码执行后,我希望能够使用i 遍历MyList l

我觉得MyCollection 中需要有一个virtual begin() 成员函数,但我无法弄清楚正确的返回类型应该是什么。

我正在尝试做的事情是否可能?我的代码的当前组织完全有可能是完全错误的。这就是我尝试过的。我的目标只是得到它,以便上面的示例驱动程序代码可以工作,因此答案可能涉及代码的完全重组。我真的只是在寻找建议。我不需要完整的答案。

【问题讨论】:

  • 为什么标准模板需要一个超类?以前从未见过。
  • @BoPersson,这是一个家庭作业。我不是在寻找问题的答案。只是一些指导。
  • 一个问题是std::list::iteratorBidirectionalIterator,而std::vector::iteratorRandomAccessIterator。你能做的最好的就是让MyCollection::iterator 具有BidirectionalIterator 的功能(如RandomAccessIterator 需要BidirectionalIterator)。你不能让它拥有RandomAccessIterator 的功能,因为std::list::iterator 根本无法使用。
  • @Cornstalks,没关系。我真的只是想获得遍历集合的功能。
  • “我觉得 MyCollection 中需要有一个虚拟的 begin() 成员函数,但我无法确定正确的返回类型应该是什么。” MyCollection&lt;T&gt;::iterator?

标签: c++ templates stl iterator


【解决方案1】:

在这种情况下,我不会为 std::vectorstd::list 编写包装器,其唯一目的是统一使用 std::list 或 std::vector。你不需要。 您想要的是以与您可以找到 here 类似的方式使用类型擦除。

您的整个想法是仅使用类型擦除迭代器实现MyCollection&lt;T&gt;,并使用类型擦除迭代器遍历任何集合。不需要MyList&lt;T&gt;MyVector&lt;T&gt;

【讨论】:

    【解决方案2】:

    MyCollection::begin 按照惯例应该返回一个MyCollection::iterator。因此MyVector::begin() 也应该返回一个至少 MyCollection::iterator 的东西。不过,它可能是更派生的类型。

    在您的情况下,MyVector::begin() 返回一个MyVector::iterator,它不是从MyCollection::iterator 派生的。这就是它失败的原因。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多