質問

I have an std::map<mpz_class,int> (for those unfamiliar, mpz_class is a class container for a very large integer number, defined by GMP, Gnu Multiprecision Library). I use a custom Comparator which uses GMP's cmp() function. In the map, I have inserted several std::pair<mpz_class,int> with correct values (they are reasonable when I print them).

However, I noticed map::find was not working correctly, so I printed what the Comparator is comparing. It turns out the second element (key) is always a very wild value integer value, like 128957236027369832796823768439267, way out of scale of the integers I'm working with.

Is there some sort of memory corruption going on that I'm unawares of? Perhaps mpz_class cannot be used in this fashion? How would I work around this problem? I haven't had this problem with other containers so far.

#include <map>
#include <gmpxx.h>
#include <iostream>

struct Equaler {
    inline bool operator()(const mpz_class a, const mpz_class b) const {
        std::cout << " about to return " << a << "," << b << "," << cmp(a,b) << "\n";
        return cmp(a, b);
    }
};

int main() {
    mpz_class x("38268");
    std::map<mpz_class,int,Equaler> map;
    map.insert(std::pair<mpz_class,int>(x,42));
    map.find(x);
    return 0;
}

Output:

about to return 38268,812462232382732367817613904064203084469901797507,-2
役に立ちましたか?

解決

The problem is your comparator. std::map expects a comparator which returns true if the first operand should be considered less than the second, and false otherwise. But cmp works differently. It doesn't return a boolean, it returns an integer, in one of three possible states:

  • negative : lhs < rhs
  • 0 : lhs == rhs
  • positive : lhs > rhs

However, a negative and a positive integer, in a boolean context, both evaluate to true, so the results of cmp do not convert correctly to what std::map expects. Change this:

return cmp(a, b);

to this:

return cmp(a, b) < 0;
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top