Почему я не могу использовать пару в качестве ключа unordered_set/unordered_map?

Оба std::set<> и std::map<> могут использовать std::pair как ключ, но почему не могут std::unordered_set<> и std::unordered_map<>?

Например:

unordered_set<pair<int,int> > S;
S.insert(make_pair(0, 1));

Не компилируется.

Ответ 1

Контейнеры unordered_* нуждаются в хеш-функции. По умолчанию они используют std::hash, но специализация std::hash для std::pair<T1,T2> отсутствует в стандартной библиотеке. С другой стороны, упорядоченные контейнеры полагаются на std::less (по умолчанию), а std::pair - operator<. Вот почему это просто работает.

Чтобы иметь неупорядоченный контейнер с pair, вам нужно будет предоставить хэш-функтор самостоятельно. Например:

struct SimpleHash {
    size_t operator()(const std::pair<int, int>& p) const {
        return p.first ^ p.second;
    }
};

std::unordered_set<std::pair<int, int>, SimpleHash> S;
S.insert(std::make_pair(0, 1));

Ответ 2

Вам нужно предоставить хэш-функцию для пары.