Пользовательский шаблон C с unordered_map

#c

#c

Вопрос:

Я пытаюсь создать пользовательский шаблон и иметь такой код:

 template <typename T>
struct Allocator {
    typedef T value_type;
    typedef size_t size_type;
    typedef ptrdiff_t difference_type;

    T *allocate(size_type n, const void *hint=0);

    T *allocate_at_least(size_type n);

    void deallocate(T *p, size_type n);
};
template <class T, class U>
bool operator==(const Allocator<T>amp;, const Allocator<U>amp;) {
    return true;
}

int main() {
    using T = long int;

    std::unordered_map<
        T,
        T,
        std::hash<T>,
        std::equal_to<T>,
        Allocator< std::pair<const T, T> >
    > a;
}
 

Он работает с vector, но где-то внутри шаблонов происходит сбой, когда я использую unordered_map.
Можете ли вы помочь мне выяснить, что я делаю не так?
Вот ошибка:

error: no matching constructor for initialization of 'std::__detail::_Hashtable_alloc<Allocator<std::__detail::_Hash_node<std::pair<const long, long>, false>>>::__buckets_alloc_type' (aka 'Allocator<std::__detail::_Hash_node_base *>')

И ссылка на код: https://godbolt.org/z/zje3EGjb6

PS. Если я заменю Allocator на std::allocator все, все работает нормально.

Комментарии:

1. Для этого требуется (3), и это останавливает автоматическую генерацию (1), поэтому вам также нужно добавить это, см. en.cppreference.com/w/cpp/memory/allocator/allocator — live (название структуры немного изменено для удобства чтения) godbolt.org/z/ecq83sG1q

2. Спасибо всем

Ответ №1:

Он должен иметь конструктор по умолчанию и конструктор, который похож на конструктор копирования, но параметризован для типа, отличного от T. Компилируется следующее.

 template <typename T>
struct Allocator {
    typedef T value_type;
    typedef size_t size_type;
    typedef ptrdiff_t difference_type;

    T* allocate(size_type n, const void* hint = 0) {
        return nullptr;
    }

    T* allocate_at_least(size_type n) {
        return nullptr;
    }

    void deallocate(T* p, size_type n) {
    }

    Allocator() {} // <= this

    template <class U>
    Allocator(const Allocator<U>amp;) {} // <= and this
};

template <class T, class U>
bool operator==(const Allocator<T>amp;, const Allocator<U>amp;) {
    return true;
}

int main() {
    using T = long int;

    std::unordered_map<
        T,
        T,
        std::hash<T>,
        std::equal_to<T>,
        Allocator< std::pair<const T, T> >
    > a;
}