Почему unordered_set с пользовательской функцией ha sh и пользовательским классом требуется начальное количество сегментов? - PullRequest
3 голосов
/ 11 марта 2020

По сути, мой вопрос: почему эта компиляция не выполняется?

#include <iostream>
#include <vector>
#include <unordered_set>
using namespace std;


int main() {
    vector<int> v{1,2,3};
    auto hash_function=[](const vector<int>& v){
        size_t hash;
        for (int i = 0; i < v.size(); ++i) {
            hash+=v[i]+31*hash;
        }
        return hash;
        };

unordered_set<vector<int>, decltype(hash_function)> s(hash_function);
std::cout<<s.bucket_count();
std::cout<<"here";


}

, но если я изменю строку unordered_set на эту

unordered_set<vector<int>, decltype(hash_function)> s(10,hash_function);

Это произойдет. Зачем ему нужно начальное количество ведра? Просто кажется странным, что использование лямбды вынуждает меня добавить начальное количество сегментов, но при использовании функтора этого не произойдет. Смотрите пример здесь: C ++ unordered_set векторов для доказательства, что версии функтора не требуется начальное количество сегментов.

Ответы [ 2 ]

4 голосов
/ 11 марта 2020

Так же, как sidenote, если у вас есть доступ к C ++ 20, вы можете сделать decltype для лямбды, не создавая ее, позволяя std::unordered_set по умолчанию создать ее.

using hash_function = decltype([](const std::vector<int>& v) {
    size_t hash = 0;
    for (int i = 0; i < v.size(); ++i) {
        hash += v[i] + 31 * hash;
    }
    return hash;
});

std::unordered_set<std::vector<int>, hash_function> s();
3 голосов
/ 11 марта 2020

Это просто потому, что такого конструктора нет.

Конструктор only unordered_set, который принимает один параметр , - это тот, который принимает экземпляр пользовательского распределителя, а не пользовательский ха sh function.

PS Вы не можете инициализировать hash в 0, в вашей пользовательской функции ha sh. Это несет повышенный риск носовых демонов . Вы должны это исправить.

...