I have two friend classes:
class Node {
private:
unsigned id_;
bool marked_;
std::set<Node> neighbors_;
friend class Graph;
......
public:
bool operator == (const Node & other) const { return id_ == other.id(); }
bool operator < (const Node & other) const { return id_ < other.id(); }
......
};
class Graph {
private:
std::set<Node> vertices_{};
void reach_set_helper(unsigned id, std::vector<unsigned> &reach_set);
......
};
I am trying to create a function that can first find a specific node in the graph vertices_
, say node v
. And then I want to change the marked_
property of the neighbors of v
. To find v
, I have to use std::find()
method. However, the return iterator of this method does not allow me to change member variables of neighbors. This is what I have tried:
Node & s = v;
std::set<Node>::iterator pos = vertices_.find(s);
const std::set<Node> & neighbors = (pos->neighbors_);
for (std::set<Node>::iterator it = neighbors.begin(); it != neighbors.end(); it++) {
if (!it->is_marked()) {
reach_set.push_back(it->id());
it->set_marked(true);
this->reach_set_helper(it->id(), reach_set);
}
}
Notice here that I have to use const std::set<Node> & neighbors
because I want to change neighbors in place. But I can't change neighbors of v
through const iterator it
, so this method does not work. I have a way to make changes to vertices_
by erase and copy back through iterator, that's not a problem. But here it is different, I am doing operations on elements of vertices, which is another set. Any suggestions?
UPDATE
Following suggestions by @walnut, I just changed marked_
to mutable, and now I'm able to write the following code
std::set<Node>::iterator pos = vertices_.find(s);
const std::set<Node> & neighbors = (pos->neighbors_);
for (const Node & nbr : neighbors) {
if (!nbr.is_marked()) {
reach_set.push_back(nbr.id());
Stack.push(nbr);
nbr.marked_ = true;
}
}
However, this does not solve the problem, as nbr
in the above code now lose the information of its own neighbors
, I still can not use this to traverse the graph.
This is so weird because nbr
is a reference of the original graph node? For example, I cannot even use this to print out my graph!
void MtxGraph::print_graph() const {
const Node & start = *vertices_.begin();
print_graph_helper(start);
}
void MtxGraph::print_graph_helper(const Node & v) const {
std::set<Node> neighbors = v.neighbors_;
for (const Node & node : neighbors) {
std::cout << v.id() << " => " << node.id() << " => ";
print_graph_helper(node);
std::cout << std::endl;
}
}
The above code also doesn't work because the reference node
doesn't preserve neighbors information of the object it refers to.