Почему std::unordered_set не использует тип CComBSTR в качестве ключа?

Когда я пытаюсь использовать 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;
}

РЕДАКТИРОВАТЬ (02.06.2019):

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

what is the design reason for std::set to have a hash function but not std::unordered_set? На самом деле все наоборот. std_set реализован как сбалансированное дерево, что означает, что его содержимое по своей природе отсортировано, но время вставки и время доступа равны O(NlogN). std::unordered_set реализован в виде хеш-таблицы, что означает, что обе эти операции выполняются за O(1). Что вы решите использовать, зависит от вашего варианта использования.
Paul Sanders 01.06.2019 22:55
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
110
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

#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;
}

Спасибо за ответы. Я понял, что означает ошибка и как исправить. Пожалуйста, смотрите мое редактирование.

Yi Bao 01.06.2019 20:10

Другие вопросы по теме