C++ 自定义迭代器 class

C++ Custom iterator class

我想实现一个自定义迭代器 class,它与典型的迭代器有一些不同。这个例子中的容器是一个向量,想法是 walk throw 它但是使用特定的语法,像这样:

int main()
{

    VectorElement E;

    for (size_t i = 0; i < 5; i++)
    {
        Element e;
        e.id = i;
        E.push_back(e);
    }

    for (ElementIterator e(E); e.end(); ++e)
        cout << "Element " << e.id << endl;

}

我尝试使用以下定义,但在两次迭代后它在 static_cast 行给了我一个分段错误。有人知道如何改进吗?谢谢

class Element
{
public:

    Element() {};    
    size_t id;
};

typedef vector<Element> VectorElement;

class ElementIterator: public Element
{
    typedef vector<Element>::iterator iter;

public:

    ElementIterator(const Element& e) : Element(e) { }    
    ElementIterator(VectorElement& ve_)
    {
        ve = &ve_;
        it = ve->begin();
    }

    ElementIterator operator++()
    {
        ++it;
        *this = static_cast<ElementIterator>(*it);
        return *this;
    }

    bool end()
    {
        if (it != ve->end() )
            return true;
        return false;
    }

    vector<Element>* ve;
    iter it;
};

我怀疑发生段错误是因为 'ElementIterator::operator++()' 增加了内部 'it' 属性,然后在没有首先验证其有效性的情况下引用它。可以这样实现:

ElementIterator::operator ++()
{
    ++it;
    if (!this->end())
        *this = static_cast<ElementIterator>(*it);
    return *this;
}

我终于使用了这个变通方法,它虽然不优雅但有效。主要问题是迭代器 "it" 被覆盖了,所以我把它放在全局范围内。

class Element
{
public:

    Element() {};    
    size_t id;
};

typedef vector<Element> VectorElement;
typedef vector<Element>::iterator iter;
iter it;

class ElementIterator: public Element
{


public:

    ElementIterator(const Element& e) : Element(e) { }    
    ElementIterator(VectorElement& ve_)
    {
        ve = &ve_;
        it = ve->begin();
    }

    ElementIterator operator++()
    {
        ++it;
        *this = static_cast<ElementIterator>(*it);
        return *this;
    }

    bool end()
    {
        if (it != ve->end() )
            return true;
        return false;
    }

    vector<Element>* ve;

};

这是不依赖于全局变量或从 'Element' 派生的替代实现:

class Element
{
public:

    Element() {};    
    size_t id;
};

class ElementIterator
{
    std::vector<Element>& ve;
    std::vector<Element>::iterator it;

public:   
    ElementIterator(std::vector<Element>& ve_) : ve(ve_)
    {    
        it = ve.begin();
    }

    ElementIterator(const ElementIterator &rhs) : ve(rhs.ve)
    {
        it = rhs.it;
    }

    ElementIterator operator++()
    {
        ++it;
        return *this;
    }

    const Element *operator ->() const
    {            
        assert(!this->end());

        return &(*it);
    }

    bool end() const
    {       
        if (it == ve.end())
            return true;

        return false;
    }
};

主要:

int main()
{    
    std::vector<Element> E;

    for (size_t i = 0; i < 5; i++)
    {
        Element e;
        e.id = i;
        E.push_back(e);
    }

    for (ElementIterator e(E); !e.end(); ++e)
        std::cout << "Element " << e->id << std::endl;
}

注意:我更改了 'ElementIterator::end' 的行为,使其 returns 'true' 在末尾时看起来更合乎逻辑。

在这里试试:

http://coliru.stacked-crooked.com/a/8bf8b1025d87a882