Barnack
Barnack

Reputation: 941

Loop in std::set by index

I'm making a program that handles dynamic graphs. Nodes and arcs are two classes, they are memorized in an array in the graph object, and are all indexed by custom ids (which are that item's position in the array). Each arc has the ids of the 2 nodes it connects, each node has a list of the ids of all arcs its connected to. (all stored in sets) An arc's destructor removes its id from the arcs set of the nodes it connected.

Now i'm writing node's destructor. It should call each arc's destructor until its set is empty. I cannot iterate through the set with an iterator, since every step the arc destructor is removing its id from the set itself.

Hence i'd need to always access last element until the set is empty; but std::set does not allow indexing like arrays and vectors, and it doesn't have a "back" like lists and stacks. How can i do that?

relevant code:

graph::arc::~arc()
    {
    owner->list_node[n1]->remove_arc(id);
    owner->list_node[n2]->remove_arc(id);
    owner->list_arc[id] = nullptr;
    }
graph::node::~node()
    {
    while (!list_arc.empty())
        {
        owner->remove_arc(list_arc[list_arc.size()-1]); //invalid, that's roughly what i want to achieve
        }
    owner->list_node[id] = nullptr;
    }

Notes owner is the graph object. owner->list_(node/arc) holds the actual pointers. Each item's id is equal to its position in graph's list.

Upvotes: 0

Views: 368

Answers (1)

JaMiT
JaMiT

Reputation: 17005

This feels like an error-prone cleanup strategy, but an improvement would probably require rewriting significantly more than what is provided in the question. (I suspect that shared and weak pointers could simplify things.) Since I lack enough information to suggest a better data structure:

For a set, it's easier to access the first element, *list_arc.begin(), than the last. (Not a huge difference, but still easier.)

Upvotes: 1

Related Questions