Почему std :: unordered_set не принимает тип CComBSTR в качестве ключа? - PullRequest
1 голос
/ 31 мая 2019

Когда я пытаюсь использовать std::unordered_set<CComBSTR> (или std::unordered_set<CAdapt<CComBSTR>>), я получаю сообщение об ошибке

c:\apps\vs2017pro\vc\tools\msvc\14.16.27023\include\unordered_set(105) : error C2280 : 'std::hash<_Kty>::hash(const std::hash<_Kty> &)' : attempting to reference a deleted function
with
[
    _Kty = ATL::CComBSTR
]

Но std::set<CComBSTR> (или std::set<CAdapt<CComBSTR>>) в порядке.Я использую Visual Studio 2017.

Что я могу сделать, чтобы по-прежнему достигать временной сложности O (1) для поиска? (Конечно, мы можем использовать пользовательскую хеш-функцию для достижения O(1) временная сложность поиска.)

Минимальный воспроизводимый пример приведен ниже.

#include "atlbase.h" 
#include <unordered_set>
#include <set>

int main()
{
    //std::unordered_set<CComBSTR> s;    // compile error
    //std::unordered_set<CAdapt<CComBSTR>> s;    // compile error

    //std::set<CComBSTR> s;    // ok
    //std::set<CAdapt<CComBSTR>> s;    // ok

    return 0;
}

РЕДАКТИРОВАТЬ (06/02/2019):

Я понял ошибку, что для CComBSTR не было хеш-функции, и мы можем создать собственную.Я хотел спросить, какова причина того, что std::set имеет хеш-функцию, а не std::unordered_set?

1 Ответ

1 голос
/ 31 мая 2019

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

#include "atlbase.h" 
#include <unordered_set>
#include <set>
#include <string>

struct HashBSTR
{
    size_t operator () (const CComBSTR &bstr)
    {
        return std::hash <std::wstring> () (bstr.m_str);
    }
};


int main()
{
    std::unordered_set <CComBSTR, HashBSTR> s;
    return 0;
}
...