来自std :: list的iterator .end()返回“ 0xcdcdcdcdcdcdcdcd”,但按预期返回.begin()

时间:2020-02-27 08:15:31

标签: c++ iterator

我正在创建一个图形,需要将迭代器返回到来自顶点的弧列表。我可以很好地返回迭代器的开头,但是当我返回迭代器的结尾时,它仅返回“ 0xcdcdcdcdcdcdcdcd”并退出并显示错误代码3。

我的头文件中有一个弧形列表,设置如下:

list<Arc<V, E>> m_edges;

和我用于返回迭代器的函数,

template<class V, class E>
inline const typename list<Arc<V, E>>::iterator Vertex<V, E>::GetIteratorBegin()
{
    const typename list<Arc<V, E>>::iterator retVal = m_edges.begin();
    return retVal;
}


template<class V, class E>
inline const typename list<Arc<V, E>>::iterator Vertex<V, E>::GetIteratorEnd()
{
    const typename list<Arc<V, E>>::iterator retVal = m_edges.end();
    return retVal;
}

然后我按如下方式使用迭代器:

list<Arc<string, string>>::iterator vertArcIterEnd = (*it).GetIteratorEnd();

我在这里使用vertArcIterEnd,这是初始化后立即执行的行:

for (list<Arc<string, string>>::iterator vertArcIterBegin = (*it).GetIteratorBegin(); vertArcIterBegin != vertArcIterEnd; ++vertArcIterBegin)

2 个答案:

答案 0 :(得分:4)

.end()返回的迭代器是集合末尾的迭代器。您永远不要取消引用它。通常,您应该与之进行比较,并且当其他比较结果与之相等时,该其他迭代器将不再有效,并且无法取消引用。

关于迭代器本身的值,将取决于它。在某些情况下,您将获得原始指针。在其他情况下,您将获得实际对象的实例。列表通常是后一种情况,因为std::list的迭代器必须重载其operator++operator--才能返回指针的nextprev指针。当前节点(请注意:它们的实际名称不会是nextprev,但可能类似于_Next_Prev。)

例如,以下是一个非常简单的图形的代码(实际上,如此简单,目前它实际上只是一棵多方树,但是它仍然显示了列表迭代器正在处理的代码类型)

#include <iostream>
#include <list>

template <class Val>
class Arc {
    Val v;    
    std::list<Arc *> children;
public:
    typename std::list<Arc *>::iterator begin() { return children.begin(); }
    typename std::list<Arc *>::iterator end() { return children.end(); }

    Arc *add_child(Val val) {
        auto ret = new Arc(val);
        children.push_back(ret);
        return ret;
    }

    Arc(Val v) : v(v) {}
    Arc() : v(-1) {}

    friend std::ostream &operator<<(std::ostream &os, Arc<Val> const &v) { 
        os << "[" << v.v;
        for (auto child : v.children) {
            os << *child;
        }
        return os << "]";
    }
};

template <class Val>
class graph {
    Arc<Val> root;
public:
    Arc<Val> *add_child(Val v, Arc<Val> *parent = nullptr) {
        if (parent == nullptr)
            return root.add_child(v);
        else
            return parent->add_child(v);
    }
    friend std::ostream &operator<<(std::ostream &os, graph const &g) { 
        return os << g.root;
    }
};

int main() { 
    graph<int> g;

    auto child = g.add_child(1);
    child->add_child(3);
    g.add_child(2);

    std::cout << g << "\n";
}

答案 1 :(得分:0)

重新启动计算机即可修复它。当我清洁解决方案并进行重建时,什么也没做;当我重新打开Visual Studio进行清洁解决方案并进行重建时,那也什么也没做。我认为重新启动PC并不是解决此问题的必要方法。我的歉意