1

私はstd::map<mpz_class,int>(なじみのない人のmpz_classために、GMP、Gnu Multiprecision Libraryによって定義された非常に大きな整数のクラスコンテナです)を持っています。cmp()GMP の関数を使用するカスタム コンパレータを使用します。マップでは、正しい値でいくつかを挿入しstd::pair<mpz_class,int>ました (それらを印刷すると妥当です)。

しかし、正しく動作していないことに気付いmap::findたので、コンパレーターが比較しているものを出力しました。2 番目の要素 (キー) は、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は、最初のオペランドが 2 番目のオペランドよりも小さいと見なされる場合は true を返し、それ以外の場合は false を返すコンパレータを想定しています。しかし、cmp動作が異なります。ブール値を返すのではなく、次の 3 つの状態のいずれかで整数を返します。

  • 負 : lhs < rhs
  • 0 : 左 == 右
  • 正: lhs > rhs

ただし、ブール値のコンテキストでは、負の整数と正の整数はどちらも true と評価されるため、 の結果は期待どおりcmpに正しく変換されません。std::mapこれを変える:

return cmp(a, b);

これに:

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