我有以下代码:
EdgeSet Graph::GetNodeOutcomingEdges(long long NodeId) {
//NodeEdgeMap is an unordereded_map
NodeEdgeMap::iterator it = NodeOutcomingEdges.find(NodeId);
if (it != NodeOutcomingEdges.end()) {
return *(*(it)).second;
}
return EdgeSet();
}
然后..
EdgeSet& OutcomingEdges = RoadGraph.GetNodeOutcomingEdges(Expandee.GetId());
因为值不必在地图中,所以我必须以某种方式解释它,在理想情况下,返回一个空的(新的)EdgeSet。我可以抛出异常,但是有必要吗?这在VS下编译得很好(可能已经考虑了RVO),但g ++不是这样。
答案 0 :(得分:1)
EdgeSet& Graph::GetNodeOutcomingEdges(long long NodeId) {
//NodeEdgeMap is an unordereded_map
NodeEdgeMap::iterator it = NodeOutcomingEdges.find(NodeId);
if (it != NodeOutcomingEdges.end()) {
return *(*(it)).second;
}
static EdgeSet emptySet;
return emptySet;
}
答案 1 :(得分:0)
假设您确实想要返回引用,以允许调用者修改返回的对象,您可以返回指向找到的对象的指针,或者如果找不到它则返回空指针:
EdgeSet* Graph::GetNodeOutcomingEdges(long long NodeId) {
//NodeEdgeMap is an unordereded_map
NodeEdgeMap::iterator it = NodeOutcomingEdges.find(NodeId);
if (it != NodeOutcomingEdges.end()) {
return it->second;
}
return 0;
}
或者,返回boost::optional<EdgeSet&>
,可以为空。
但是你不应该返回引用&#34;只是因为&#34;,如果你希望调用者能够引用存储在地图中的相同对象,你应该返回引用,并且也能够修改它。否则,返回副本或const引用会更好。
答案 2 :(得分:0)
这只是一种可行的方法:在Graph类中,定义一个EdgeSet类型的空成员变量,其中一些属性将其标识为空,例如“mEmptyFlag”boolean:
class Graph {
...
static EdgeSet mEmptyNode(params defining empty node here);
...
}
EdgeSet Graph::GetNodeOutcomingEdges(long long NodeId) {
//NodeEdgeMap is an unordereded_map
NodeEdgeMap::iterator it = NodeOutcomingEdges.find(NodeId);
if (it != NodeOutcomingEdges.end()) {
return *(*(it)).second;
}
return Graph::mEmptyNode;
}
callerFunct {
EdgeSet& OutcomingEdges = RoadGraph.GetNodeOutcomingEdges(Expandee.GetId());
if (OutcomingEdges.mEmptyflag==true) {
deal with empty node here
} else {
....
}
}
甚至更好的封装,隐藏mEmptyFlag并为EdgeSet提供“IsEmpty()”函数。
答案 3 :(得分:-3)
NodeEdgeMap::iterator Graph::GetNodeOutcomingEdges(long long NodeId) {
return NodeOutcomingEdges.find(NodeId);
}