Как специализировать std::hash для типа из другой библиотеки

Итак, библиотека, которую я использую, имеет перечисление (скажем, оно называется LibEnum). Мне нужно иметь std::unordered_set из LibEnum, но я получаю ошибку компиляции, что для него нет специализированного std::hash. Я мог бы легко написать это и просто вернуть число значений (первый элемент равен 0, второй 1 и т. д.), но где именно я должен указать эту специализацию и как она должна выглядеть? Я не могу изменить исходники библиотеки.

  enum LibEnum { A, B, C, D};
  std::unordered_set <LibEnum> mySet;
  //need std::hash for LibEnum
  //how should it look like?

person user1873947    schedule 11.02.2013    source источник
comment
Поскольку вы используете enum, в этом документе описаны расширения enum, представленные в С++ 11 (на всякий случай, если вы не в курсе).   -  person hmjd    schedule 11.02.2013
comment
@hmjd интересно читать, спасибо.   -  person user1873947    schedule 11.02.2013


Ответы (1)


Вы можете просто специализировать std::hash для своего типа:

namespace std {
    template <>
    struct hash<FullyQualified::LibEnum> {
        size_t operator ()(FullyQualified::LibEnum value) const {
            return static_cast<size_t>(value);
        }
    };
}

В качестве альтернативы вы можете определить тип hash где угодно и просто указать его в качестве дополнительного аргумента шаблона при создании экземпляра std::unordered_map<FooEnum>:

// Anywhere in your code prior to usage:

struct myhash {
    std::size_t operator ()(LibEnum value) const {
        return static_cast<std::size_t>(value);
    }
};

// Usage:

std::unordered_map<LibEnum, T, myhash> some_hash;

Ни один из методов не требует изменения библиотеки.

person Konrad Rudolph    schedule 11.02.2013