I am trying to create a custom template, and have such code:
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>&, const Allocator<U>&) {
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;
}
It works with vector, but it fails somewhere inside the templates when I use unordered_map. Can you help me to figure out what I am doing wrong? Here is the error:
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 *>')
And link to code: https://godbolt.org/z/zje3EGjb6
P.S. If I replace Allocator
to std::allocator
everything works fine.
CodePudding user response:
It needs to have a default constructor and a constructor that is like a copy constructor but parametrized on a non-T type. The following compiles.
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>&) {} // <= and this
};
template <class T, class U>
bool operator==(const Allocator<T>&, const Allocator<U>&) {
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;
}