1

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

但是,我注意到map::find工作不正常,所以我打印了 Comparator 正在比较的内容。事实证明,第二个元素(键)总是一个非常疯狂的整数值,比如 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
4

1 回答 1

2

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

  • 负数:lhs < rhs
  • 0 : lhs == rhs
  • 正: lhs > rhs

但是,在布尔上下文中,一个负整数和一个正整数都评估为真,因此结果cmp不能正确转换为std::map预期的结果。改变这个:

return cmp(a, b);

对此:

return cmp(a, b) < 0;
于 2013-11-08T22:08:42.307 回答