How to iterate properly across a const set?
I'm working on a program that's supposed to represent a graph. My issue is in my printAdjacencyList function. Basically, I have a Graph ADT that has a member variable "nodes", which is a map of the nodes of that graph. Each Node has a set of Edge* to the edges it is connected to. I'm trying to iterate across eac开发者_StackOverflowh node in the graph and each edge of a node.
void MyGraph::printAdjacencyList() {
std::map<std::string, MyNode*>::iterator mit;
std::set<MyEdge*>::iterator sit;
for (mit = nodes.begin(); mit != nodes.end(); mit++ ) {
std::cout << mit->first << ": {";
const std::set<MyEdge*> edges = mit->second->getEdges();
for (sit = edges.begin(); sit != edges.end(); sit++) {
std::pair<MyNode*, MyNode*> edgeNodes = *sit->getEndpoints();
}
}
std::cout << " }" << std::endl;
}
getEdges is declared as:
const std::set<MyEdge*>& getEdges() { return edges; };
and get Endpoints is declared as:
const std::pair<MyNode*, MyNode*>& getEndpoints() { return nodes; };
The compiler error I'm getting is:
MyGraph.cpp:63: error: request for member `getEndpoints' in
`*(&sit)->std::_Rb_tree_const_iterator<_Tp>::operator->
[with _Tp = MyEdge*]()', which is of non-class type `MyEdge* const'
MyGraph.cpp:63: warning: unused variable 'edgeNodes'
I have figured out that this probably means I'm misusing const somewhere, but I can't figure out where for the life of me. Any information would be appreciated. Thanks!
Try changing sit
to a const_iterator
. Change mit
to a const_iterator
too while you're at it. Also, getEdges()
and getEndpoints()
should be const functions. Lastly, because operator->()
has a higher precedence than the unary operator*()
, you probably want to say edgeNodes = (*sit)->getEndPoints()
inside the inner-loop.
Not as much of a problem but you should consider having the iterator instances as local to the loops.
It's hard to tell anything definite without something compilable, but
const std::set<MyEdge*>& getEdges() { return edges; };
and
const std::pair<MyNode*, MyNode*>& getEndpoints() { return nodes; };
should technically be const methods since they don't modify the class and return a const reference.
const std::set<MyEdge*>& getEdges() const { return edges; };
const std::pair<MyNode*, MyNode*>& getEndpoints() const { return nodes; };
This in combination with const_iterator
might solve your constness problems.
However, your particular error might be that *it->foo()
= *(it->foo())
is different from (*it)->foo()
s/std::set<MyEdge*>::iterator sit;/std::set<MyEdge*>::const_iterator sit;/
and ditto for mit. In other words, const_iterator
is what you need here.
精彩评论