key comparisons in c++ map not working
I have created a map with ClassExpression
as the key and std::string
as the value. The key comparator is given below
class ClassExpressionComparator {
public:
bool operator()(const ClassExpression& lhs,
const ClassExpression& rhs) const {
return ((lhs.quantifier == rhs.quantifier) &&
(lhs.property.c开发者_运维知识库ompare(rhs.property) == 0) &&
(lhs.concept.compare(rhs.concept) == 0));
}
};
ClassExpression contains the 3 fields mentioned in the comparator. I compare all the 3 fields. When I use find() of map, even if the key is not present in the map, it says that it found the key and gives an existing key as the result (getting first key as the result).
I tried the following
boost::shared_ptr< std::map<ClassExpression, std::string,
ClassExpressionComparator> > cemap(
new std::map<ClassExpression,
std::string, ClassExpressionComparator>());
ClassExpression ce1;
ce1.quantifier = com::xxxx::kb::SOME;
ce1.property = "<http://www.w3.org/2002/07/acts-on>";
ce1.concept = "<http://www.w3.org/2002/07/Tissue>";
populateMap(cemap, ce1);
ClassExpression ce2;
ce2.quantifier = com::xxxx::kb::SOME;
ce2.property = "<http://www.w3.org/2002/07/contained-in>";
ce2.concept = "<http://www.w3.org/2002/07/HeartValve>";
populateMap(cemap, ce2);
ClassExpression ce3;
ce3.quantifier = com::xxxx::kb::SOME;
ce3.property = "<http://www.w3.org/2002/07/has-location>";
ce3.concept = "<http://www.w3.org/2002/07/Endocardium>";
std::map<ClassExpression, std::string, ClassExpressionComparator>::iterator
ceIterator = cemap->find(ce3);
if (ceIterator == cemap->end()) {
std::cout << "Not found" << std::endl;
}
else {
std::cout << "Found; concept = " << ceIterator->second << std::endl;
}
ClassExpressionComparator cmp;
std::cout << "compare: " << cmp(ce1, ce3) << std::endl;
populateMap()
just does an insert, in my actual code, I do a few more things in it, I wanted to keep the same flow, so left it that way.
The output of cmp(ce1, ce3)
is 0 but when I do a find(ce3)
, the result is that it found it at the first key position instead of returning end()
. Where am I going wrong here?
Thank you.
Raghava.
You wrote an equality comparison. map
requires a less-than comparison. (Or greater-than if you want the keys in decreasing order.)
My usual idiom for doing this:
bool operator()(const ClassExpression& lhs,
const ClassExpression& rhs) const {
return lhs.quantifier < rhs.quantifier? true
: rhs.quantifier < lhs.quantifier? false
: lhs.property.compare(rhs.property) < 0? true
: lhs.property.compare(rhs.property) > 0? false
: lhs.concept.compare(rhs.concept) < 0;
}
The map
is a sorted container, the comparator operator it's looking for is one that implements a strict weak ordering, like <
. You're giving it an equals operator, which will screw up the ordering.
精彩评论