无法基于STL迭代器编写自己的迭代器

时间:2013-01-19 14:10:55

标签: c++ templates stl iterator

在尝试基于链表实现容器Set时,我遇到了一些问题。 是的,我知道有一套STL实现,但这是为了做作业。 :)

所以,这就是我到目前为止所做的:

我的Set.h文件看起来像这样:

template <class T>
class Set {
private:
    typedef std::list<T> base_container;
    base_container items;
public:
    class myIterator {
    public:
        typename base_container::iterator base_iterator;
        myIterator() { }
    };
    void addItem(const T item) {
        items.push_back(item);
    }
    typedef typename Set<T>::myIterator setIterator;
    setIterator begin() { return items.begin(); }
    setIterator end() { return items.end(); }
    Set<T>(void) { }
    ~Set<T>(void) { }
};

现在,main.cpp:

#include "Set.h"

int main(void) {
    Set<int> mySet;

    mySet.addItem(1);
    mySet.addItem(2);
    mySet.addItem(3);
    mySet.addItem(4);

    Set<int>::myIterator x;
    x = mySet.begin();       // produces an error about non-convertible types.

    return EXIT_SUCCESS;
}

错误如下:

error C2664: 'Set<T>::myIterator::myIterator(const Set<T>::myIterator &)' : cannot convert parameter 1 from 'std::_List_iterator<_Mylist>' to 'const Set<T>::myIterator &' 

显然我搞砸了,但我不确定代码的哪一部分实际上是问题。 有关如何解决此问题的任何建议?任何有用的信息将不胜感激。

感谢。 :)

3 个答案:

答案 0 :(得分:2)

您的方法存在许多问题。

正如其他人所说,你无法从底层类型创建迭代器类型:

setIterator begin() { return items.begin(); }
setIterator end() { return items.end(); }

这可以通过在您的类型中添加构造函数来解决:

class myIterator {
    typedef typename base_container::iterator base_iterator_type;
public:
    explicit myIterator(base_iterator_type i) : base_iterator(i) { }
    base_iterator_type base_iterator;
    myIterator() { }
};

此构造函数应该是显式的,这意味着您需要更改创建它的方式:

setIterator begin() { return setIterator(items.begin()); }

下一个问题是你的类型没有实现迭代器接口,它没有提供operator++operator*等等,并且它没有定义嵌套类型,例如{{1} }和value_type即它不是一个迭代器(只是给它一个带有“iterator”的名称并不能使它成为现实!)

一旦你修复了它并且你的类型是一个有效的迭代器,你会发现你的容器不能用于STL风格的算法,因为它没有实现容器要求。除其他外,它应该提供一个名为iteratory_category而不是iterator的嵌套类型,以便其他模板代码可以使用setIterator而无需关心S::iteratorS还是一个std::set<T>。不要将其称为Set<T>,只需将其称为Set<T>::setIterator即可。同样在这种情况下,没有必要定义Set<T>::iterator(没有人关心它是你的!:-)然后有一个typedef来调用它myIterator,只需在第一个地方命名具有正确名称的类型,然后你不需要typedef。

答案 1 :(得分:1)

您可以从std::iterator<T>派生并提供适当的迭代器类别标记。这将自动为您的迭代器提供所需的嵌套类型,例如value_type T。您仍然需要编写operator++operator*等函数成员(取决于您的迭代器类别,例如,对于随机访问迭代器,您还需要operator[]

答案 2 :(得分:1)

问题在于:

setIterator begin() { return items.begin(); }
setIterator end() { return items.end(); }

您尝试返回的值的类型错误。它们的类型为base_iterator而不是setIterator,并且无法隐式地将前者转换为后者。