STL映射被mpz_class(GMP)值损坏

时间:2013-11-08 21:57:28

标签: c++ map stl gmp

我有std::map<mpz_class,int>(对于那些不熟悉的人,mpz_class是一个非常大整数的类容器,由GMP,Gnu Multiprecision Library定义)。我使用自定义Comparator,它使用GMP的cmp()函数。在地图中,我插入了几个具有正确值的std::pair<mpz_class,int>(当我打印它们时它们是合理的。)

但是,我注意到map::find无法正常工作,所以我打印了比较器正在比较的内容。事实证明,第二个元素(键)总是一个非常狂野的值整数值,如128957236027369832796823768439267,超出了我正在使用的整数的范围。

是否存在某些我不知道的内存损坏?也许mpz_class不能以这种方式使用?我该如何解决这个问题?到目前为止,我还没有遇到过其他容器的问题。

#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;
}

输出:

about to return 38268,812462232382732367817613904064203084469901797507,-2

1 个答案:

答案 0 :(得分:2)

问题是你的比较器。 std::map期望比较器在第一个操作数应小于第二个时返回true,否则返回false。但cmp的工作方式不同。它不返回布尔值,它返回一个整数,处于三种可能状态之一:

  • 否定:lhs&lt; RHS
  • 0:lhs == rhs
  • 正面:lhs&gt; RHS

但是,布尔上下文中的负整数和正整数都计算为true,因此cmp的结果无法正确转换为std::map期望的结果。改变这个:

return cmp(a, b);

到此:

return cmp(a, b) < 0;