dimanche 2 janvier 2022

unexpected error in unordered_map iterator comparison

I have a simple map std::map<string, my_namespace::MyType>, I am using c++11 so I replaced it with unordered_map for performance reasons. I got the following error when comparing an iterator with end().

auto cit = str_map_.find(str);
if (cit != str_map_.end()) {
   ...
}

In instantiation of 'bool my_namespace::operator!=(const T1&, const T2&) [with T1 = std::__detail::_Node_iterator<std::pair<const std::__cxx11::basic_string, my_namespace::MyType, false, true>; T2 = std::__detail::_Node_iterator<std::pair\ <const std::__cxx11::basic_string, my_namespace::MyType, false, true>]': no matching function ...

I debugged it down to my rather creative comparison operators for my_namespace::MyType:

template <class T>
struct MyType {
    T* mt_;
};

struct MyTempClass {
    std::string mtc_;

    static int Compare(MyType<MyTempClass> const& lhs, MyType<MyTempClass> const& rhs) {
        return lhs.mt_->mtc_.compare(rhs.mt_->mtc_);
    }

    static int Compare(std::string const& lhs, MyType<MyTempClass> const& rhs) {
        return lhs.compare(rhs.mt_->mtc_);
    }

    static int Compare(MyType<MyTempClass> const& lhs, std::string const& rhs) {
        return lhs.mt_->mtc_.compare(rhs);
    }
};

template <class T1, class T2>
bool operator !=(T1 const& lhs, T2 const& rhs) {
    int res = MyTempClass::Compare(lhs, rhs);
    return (res != 0);
}

template <class T1, class T2>
bool operator ==(T1 const& lhs, T2 const& rhs) {
    int res = MyTempClass::Compare(lhs, rhs);
    return (res != 0);
}

static std::unordered_map<std::string, MyType<MyTempClass>> my_map;

But I am still puzzled why it did happen: the same code works fine with a plain map, and values type should not be involved in iterator comparisons?

Aucun commentaire:

Enregistrer un commentaire