Почему при использовании настраиваемой структуры в качестве ключа boost :: bimap находит неправильную запись? - PullRequest
0 голосов
/ 06 апреля 2020

У меня есть собственная структура, я сопоставляю некоторые данные, используя boost :: bimap. К сожалению, bimap find () не работает должным образом. Ниже приведен минимальный пример для демонстрации:

#include <utility>
#include <boost/bimap.hpp>

struct S{
    int a;
    int b;
};
bool operator<(const S& lhs, const S& rhs) {          
    return std::tie(lhs.a, lhs.b) <
            std::tie(lhs.a, lhs.b);
}
bool operator==(const S& lhs, const S& rhs) {
   return 
        lhs.a == rhs.a &&
        lhs.b == rhs.b;
}

int main() {
    boost::bimap<S, int> bmap;

    S s0{0, 0};
    S s1{0, 1};

    bmap.left.insert(std::make_pair(s0, 0));
    bmap.left.insert(std::make_pair(s1, 1));

    auto it0 = bmap.left.find(s0);
    assert(it0 != bmap.left.end());
    auto res0_s = it0->first;
    auto res0 = it0->second;
    assert(res0_s == s0);
    assert(res0 == 0);

    auto it1 = bmap.left.find(s1);
    assert(it1 != bmap.left.end());
    auto res1_s = it1->first;
    auto res1 = it1->second;
    assert(res1_s == s1);
    assert(res1 == 1);
}

Последние два утверждения терпят неудачу (GDB показывает, что res1_s == s0). Я подозреваю, что реализация оператора <как-то не работает, как задумано. Как я понимаю, std :: t ie, он должен просто лексикографически сравнить два операнда, и этого должно быть достаточно, чтобы использовать произвольные структуры в качестве ключа для карт. </p>

Спасибо за вашу помощь.

1 Ответ

0 голосов
/ 06 апреля 2020
bool operator<(const S& lhs, const S& rhs) {          
    return std::tie(lhs.a, lhs.b) <
           std::tie(lhs.a, lhs.b);
}

Вы дали одинаковые аргументы обоим вызовам функций std::tie, поэтому ваш operator< всегда возвращает false. Измените его на следующее.

bool operator<(const S& lhs, const S& rhs) {          
    return std::tie(lhs.a, lhs.b) <
           std::tie(rhs.a, rhs.b);
}
...