2

I managed to figure out the answer to this question as I was writing it. Keeping it posted to hopefully aide future devs that run into similar issue.

Here's a quick rundown: I have a directed, weighted map class. I keep track of all my nodes in: vector<Node> nodes; I keep track of all the nodes' adjacent nodes in map<Node, <map<Node, int>> connections

When I try doing a traversal through the Graph and I reach a node that does not have any adjacent nodes it will crash the program because my map throws out_of_range exception.

After looking online I see someone has the solution of using this line of code when they are adding nodes: (void) connections[node];. If I remove this line of code, I get the out_of_range exception from the map class's .at() function, but with this line of code, it somehow avoids that exception.

My Question: What is the line of code doing that avoids the exception from being thrown? My best guess right now is that the line of code is somehow creating an empty adjacency list and my for-each loop doesn't get the exception

    set<Node> nodes; // {n1, n2...nn}
    map<Node, map<Node, int>> connections; //Connections between the nodes and their weights

    //Add node to graph
    void add(Node node) {
        nodes.insert(node); //add to node list
        (void) connections[node]; //This is the magic line!!
    }

    bool DFS(N start, N target) {

        for (Node node : nodes) {

    //This for-each loop crashes when the node in the .at() doesn't exist in the connections map
            for (pair<N, int> connectedNode : connections.at(node)) {
                if (target == connectedNode.first) {
                    return true;
                }
            }
        }
        return false;
    }

Ryan Russell
  • 497
  • 5
  • 17

1 Answers1

1

As I was writing the question I was able to answer my own question. Love a good Rubber Ducky moment. Hopefully, this question can aide future devs who also miss the very basic answer to this question.

In stl::map the [ ] operator will get a reference to the value of the key inside the [ ] if it exists, if it doesn't exist it creates one. So in the add(Node node) function the (void)connections[node] was actually creating the node in the adjacency map.

The (void) before the line is telling the compiler to ignore any warnings about this because it's technically an incomplete line of code (according to the compiler). Read more about the meaning of (void) here

Ryan Russell
  • 497
  • 5
  • 17
  • 1
    And this question shows exactly why this kind of code is bad: it uses a side-effect to do what it should do implicitly without confusing the reader and trying to silence the compiler. – Sami Kuhmonen Dec 06 '19 at 05:57