2
votes

I have a struct as key for std::unordered_map. I have written custom hash function and comparison predicate. When I try to compile the code I am getting the following error-

error: static assertion failed: key equality predicate must be invocable with two arguments of key type 1831 | static_assert(__is_invocable<const _Equal&, const _Key&, const _Key&>{},

Following is the code snippet-

using namespace std;
struct keys
{
    int port_num;
};

struct fields
{
    int priority;
};

struct container_hash {
    std::size_t operator()(struct keys const& c) const {
        return hash<int>{}(c.port_num);
    }
};

struct container_equal {
    bool operator()(struct keys const& k1, struct keys const& k2)
    {
        return k1.port_num == k2.port_num;
    }
};

int main()
{
    unordered_map<struct keys, struct fields, container_hash, container_equal> hashmap;
    struct keys k;
    k.port_num = 8;
    struct fields f;
    f.priority = 2;
    hashmap[k] = f;
}
1
Unrelated: In C++ you don't need the struct before using a struct. For example struct keys k; should be just keys k;churill

1 Answers

2
votes
bool operator()(struct keys const& k1, struct keys const& k2)

must be const

//                                                            VVVVV
bool operator()(struct keys const& k1, struct keys const& k2) const

You can also see it in the error message that the function must be callable on a const reference of the object

//                           VVVVV       V
static_assert(__is_invocable<const _Equal&, const _Key&, const _Key&>{},

I couldn't find anything in the standard that explicitly says, it must be const, at most in the named requirement for comparators:

[...] evaluation of that expression is not allowed to call non-const functions through the dereferenced iterators.