zadam oczywiste pytanie, ale to naprawdę zmienia wszystko:
jest pojęcie równości w map
zgodny z pojęciem równości w unordered_map
?
przykładu niekompatybilnych definicje:
struct Point3D { std::int32_t x, y, z };
struct MapLess {
bool operator()(Point3D const& left, Point3D const& right) const {
return std::tie(left.x, left.y) < std::tie(right.x, right.y);
}
};
bool operator==(Point3D const& left, Point3D const& right) {
return std::tie(left.x, left.z)
== std::tie(right.x, right.z);
}
W ten (contrived) wypadku możemy mieć
map
: (1, 2, 3)
i (1, 3, 3)
unordered_map
: (1, 2, 3)
i (1, 2, 4)
i naiwny look-up będą zgłaszać, że map
jest zawarty w unordered_map
, ponieważ ponieważ oba mają ten sam rozmiar doprowadziłoby do błędnego wniosku, że są one równe.
Rozwiązanie jeśli kanoniczny pojęcie równości istnieje jest sprawdzenie, po każdym look-up, że wynik look-up jest faktycznie taka sama jak oryginał.
template <typename M1, typename M2>
bool equal(M1 const& left, M2 const& right) {
if (left.size() != right.size()) { return false; }
for (auto const& e: left) {
auto const it = right.find(e.first);
if (it == right.end()) { return false; }
if (it->first != e.first) { return false; }
if (it->second != e.second) { return false; }
}
return true;
}
Uwaga: to może być przepisany z std::all
i pojedynczym logicznej wypowiedzi; to kwestia gustu, wolę ją rozbić.
Jeśli nie kanoniczny pojęcie równości istnieje, wtedy odwrotny look-up może zastąpić sprawdzenie równości:
template <typename M1, typename M2>
bool equal(M1 const& left, M2 const& right) {
if (left.size() != right.size()) { return false; }
for (auto e = left.begin(), end = left.end(); e != end; ++e) {
auto const it = right.find(e->first);
if (it != right.end()) { return false; }
if (left.find(it->first) != e) { return false; }
if (it->second != e->second) { return false; }
}
return true;
}
To oczywiście nieco droższe.
Można dokonać iteracji na jednym lub drugim i sprawdzić, czy wartości dla każdego klucza są takie same. – Chris
Czy używasz gmock? https://groups.google.com/forum/#! topic/googlemock/kz4tACpCBME UnorderedElementsAreArray będzie ładnie działać tutaj. – FDinoff
@FDinoff Nope tylko test Google! Nigdy nie korzystałem jeszcze z Gmocka, ale twój komentarz jest interesujący! czy łatwo dołączyć Gmock do GTest? – Aminos