iterator .end () из std :: list возвращает «0xcdcdcdcdcdcdcdcd», но .begin (), как и ожидалось - PullRequest
0 голосов
/ 27 февраля 2020

Я создаю граф, и мне нужно вернуть итератор в список дуг, идущих из вершины. Я могу нормально вернуть начало итератора, но когда я возвращаю конец итератора, он просто возвращает «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 ]

4 голосов
/ 27 февраля 2020

Итератор, возвращаемый .end(), находится за концом коллекции. Вы никогда не должны разыменовывать это. Обычно вы должны сравнивать с ним, и когда что-то еще сравнивается равным ему, этот другой итератор больше не действителен и не может быть разыменован.

Что касается значения самого итератора, оно будет зависеть , В некоторых случаях вы получите необработанный указатель. В других случаях вы получите экземпляр реального объекта. Список обычно будет последним случаем, потому что итератор для std::list должен перегружать свои operator++ и operator--, чтобы вернуть указатели next и prev для текущего узла (примечание: их действительные имена выиграли ' может быть next и prev, но может быть что-то вроде _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";
}
0 голосов
/ 27 февраля 2020

Перезагрузка моего компьютера исправила это. Когда я делал чистое решение и перестраивал, это ничего не делало, и когда я снова открывал Visual Studio и делал чистое решение и перестройку, это тоже ничего не делало. Я не думал, что перезагрузка моего P C была необходимым решением для этого. Мои извинения

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...