开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜