Функция определения неисправности ha sh для пользовательского типа в unordered_multimap на MacOS - PullRequest
0 голосов
/ 03 апреля 2020

Поэтому я хочу использовать пользовательский тип (здесь SWrapper) в качестве типа ключа для unordered_multimap. Я определил класс ha sh, полученный из стандартной функции хеширования для строк, и включил класс хеширования в тип мультикарты. Некоторый код, который воспроизводит ошибку, показан ниже. Это компилируется на Arch Linux с g ++ и clang ++, но на MacOS с clang ++ я получаю ошибки:

#include <unordered_map>
#include <functional>
#include <string>

class SWrapper {
    public:
    SWrapper() {
        (*this).name = "";
    }

    SWrapper(std::string name) {
        (*this).name = name;
    }

    bool operator==(SWrapper const& other) {
        return (*this).name == other.name;
    }

    std::string name;
};

class SWrapperHasher {
    size_t operator()(SWrapper const& sw) const {
        return std::hash<std::string>()(sw.name);
    }
};

int main(int argc, char* argv[]) {
    auto mm = std::unordered_multimap<SWrapper, int, SWrapperHasher>();
    return 0;
}

Запуск g++ -std=c++11 -Wall -Wpedantic -Wextra hash_map_test.cpp -o hash_map_test на Arch Linux (или clang++) компилирует код без ошибок. Однако в MacOS, используя ту же команду, я получаю следующее сообщение об ошибке:

In file included from hash_map_test.cpp:1:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/unordered_map:408:
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/__hash_table:868:5: error: 
      static_assert failed due to requirement 'integral_constant<bool, false>::value' "the
      specified hash does not meet the Hash requirements"
    static_assert(__check_hash_requirements<_Key, _Hash>::value,
    ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/__hash_table:883:1: note: in
      instantiation of template class
      'std::__1::__enforce_unordered_container_requirements<SWrapper, SWrapperHasher,
      std::__1::equal_to<SWrapper> >' requested here
typename __enforce_unordered_container_requirements<_Key, _Hash, _Equal>::type
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/unordered_map:1682:26: note: while
      substituting explicitly-specified template arguments into function template
      '__diagnose_unordered_container_requirements'
    static_assert(sizeof(__diagnose_unordered_container_requirements<_Key, _Hash, _Pred>(...
                         ^
hash_map_test.cpp:29:15: note: in instantiation of template class
      'std::__1::unordered_multimap<SWrapper, int, SWrapperHasher, std::__1::equal_to<SWrapper>,
      std::__1::allocator<std::__1::pair<const SWrapper, int> > >' requested here
    auto mm = std::unordered_multimap<SWrapper, int, SWrapperHasher>();
              ^
1 error generated.

Я пытался интерпретировать сообщение об ошибке, но я действительно не понимаю, что с ним делать. Если у кого-нибудь есть какие-либо предложения относительно того, что здесь происходит, и как я могу обойти это на MacOS, это будет очень признательно!

1 Ответ

3 голосов
/ 03 апреля 2020

В жалобе компилятора, к сожалению, не сказано, какое требование не было выполнено. В этом случае проблема возникает из-за SWrapperHasher::operator(), являющегося private. Отметив, что public (изменение class на struct делает это неявно) делает неупорядоченную карту легальной.

...