[Bug libstdc++/59751] New: Hash tables don't use allocator_traits
martinho.fernandes at gmail dot com
gcc-bugzilla@gcc.gnu.org
Fri Jan 10 09:46:00 GMT 2014
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59751
Bug ID: 59751
Summary: Hash tables don't use allocator_traits
Product: gcc
Version: 4.8.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libstdc++
Assignee: unassigned at gcc dot gnu.org
Reporter: martinho.fernandes at gmail dot com
Take the following program:
---
#include <unordered_map>
#include <functional>
#include <utility>
#include <cstddef>
template <typename T>
struct my_allocator {
using value_type = T;
T* allocate(std::size_t) { return nullptr; }
void deallocate(T*, std::size_t) {}
};
int main() {
using map_type = std::unordered_map<int, double, std::hash<int>,
std::equal_to<int>, my_allocator<std::pair<const int, double>>>;
map_type m { { 1, 1. } , { 2, 2. } };
}
---
As far as I understand the allocator used is a minimally complete.
std::allocator_traits can fill in all the rest, so the program is well-formed.
However, attempting compilation with GCC 4.8.1 results in:
---
In file included from /usr/include/c++/4.8/unordered_map:47:0,
from main.cpp:1:
/usr/include/c++/4.8/bits/hashtable.h: In instantiation of ‘class
std::_Hashtable<int, std::pair<const int, double>, my_allocator<std::pair<const
int, double> >, std::__detail::_Select1st, std::equal_to<int>, std::hash<int>,
std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash,
std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false,
false, true> >’:
/usr/include/c++/4.8/bits/unordered_map.h:100:18: required from ‘class
std::unordered_map<int, double, std::hash<int>, std::equal_to<int>,
my_allocator<std::pair<const int, double> > >’
main.cpp:17:14: required from here
/usr/include/c++/4.8/bits/hashtable.h:194:47: error: no type named ‘pointer’ in
‘struct my_allocator<std::pair<const int, double> >’
typedef typename _Alloc::pointer pointer;
^
/usr/include/c++/4.8/bits/hashtable.h:195:55: error: no type named
‘const_pointer’ in ‘struct my_allocator<std::pair<const int, double> >’
typedef typename _Alloc::const_pointer const_pointer;
^
/usr/include/c++/4.8/bits/hashtable.h:196:55: error: no type named ‘reference’
in ‘struct my_allocator<std::pair<const int, double> >’
typedef typename _Alloc::reference reference;
^
/usr/include/c++/4.8/bits/hashtable.h:197:55: error: no type named
‘const_reference’ in ‘struct my_allocator<std::pair<const int, double> >’
typedef typename _Alloc::const_reference const_reference;
^
/usr/include/c++/4.8/bits/hashtable.h:317:8: error: no class template named
‘rebind’ in ‘struct my_allocator<std::pair<const int, double> >’
_Node_allocator_type;
^
/usr/include/c++/4.8/bits/hashtable.h:319:8: error: no class template named
‘rebind’ in ‘struct my_allocator<std::pair<const int, double> >’
_Bucket_allocator_type;
^
/usr/include/c++/4.8/bits/hashtable.h:321:75: error: no class template named
‘rebind’ in ‘struct my_allocator<std::pair<const int, double> >’
using __before_begin = __detail::_Before_begin<_Node_allocator_type>
^
In file included from /usr/include/c++/4.8/unordered_map:48:0,
from main.cpp:1:
/usr/include/c++/4.8/bits/unordered_map.h: In instantiation of ‘class
std::unordered_map<int, double, std::hash<int>, std::equal_to<int>,
my_allocator<std::pair<const int, double> > >’:
main.cpp:17:14: required from here
/usr/include/c++/4.8/bits/unordered_map.h:116:49: error: no type named
‘pointer’ in ‘std::unordered_map<int, double, std::hash<int>,
std::equal_to<int>, my_allocator<std::pair<const int, double> >
>::allocator_type {aka struct my_allocator<std::pair<const int, double> >}’
typedef typename allocator_type::pointer pointer;
^
/usr/include/c++/4.8/bits/unordered_map.h:117:54: error: no type named
‘const_pointer’ in ‘std::unordered_map<int, double, std::hash<int>,
std::equal_to<int>, my_allocator<std::pair<const int, double> >
>::allocator_type {aka struct my_allocator<std::pair<const int, double> >}’
typedef typename allocator_type::const_pointer const_pointer;
^
/usr/include/c++/4.8/bits/unordered_map.h:118:50: error: no type named
‘reference’ in ‘std::unordered_map<int, double, std::hash<int>,
std::equal_to<int>, my_allocator<std::pair<const int, double> >
>::allocator_type {aka struct my_allocator<std::pair<const int, double> >}’
typedef typename allocator_type::reference reference;
^
/usr/include/c++/4.8/bits/unordered_map.h:119:56: error: no type named
‘const_reference’ in ‘std::unordered_map<int, double, std::hash<int>,
std::equal_to<int>, my_allocator<std::pair<const int, double> >
>::allocator_type {aka struct my_allocator<std::pair<const int, double> >}’
typedef typename allocator_type::const_reference const_reference;
^
In file included from /usr/include/c++/4.8/unordered_map:47:0,
from main.cpp:1:
/usr/include/c++/4.8/bits/hashtable.h: In instantiation of
‘std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
_RehashPolicy, _Traits>::_Hashtable(_InputIterator, _InputIterator,
std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
_RehashPolicy, _Traits>::size_type, const _H1&, const _H2&, const _Hash&, const
_Equal&, const _ExtractKey&, const allocator_type&) [with _InputIterator =
const std::pair<const int, double>*; _Key = int; _Value = std::pair<const int,
double> _Alloc = my_allocator<std::pair<const int, double> > _ExtractKey =
std::__detail::_Select1st; _Equal = std::equal_to<int> _H1 = std::hash<int> _H2
= std::__detail::_Mod_range_hashing; _Hash =
std::__detail::_Default_ranged_hash; _RehashPolicy =
std::__detail::_Prime_rehash_policy; _Traits =
std::__detail::_Hashtable_traits<false, false, true> std::_Hashtable<_Key,
_Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy,
_Traits>::size_type = long unsigned int; std::_Hashtable<_Key, _Value, _Alloc,
_ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>::allocator_type =
my_allocator<std::pair<const int, double> >]’:
/usr/include/c++/4.8/bits/hashtable.h:419:26: required from
‘std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
_RehashPolicy, _Traits>::_Hashtable(std::initializer_list<_Value>,
std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
_RehashPolicy, _Traits>::size_type, const _H1&, const key_equal&, const
allocator_type&) [with _Key = int; _Value = std::pair<const int, double> _Alloc
= my_allocator<std::pair<const int, double> > _ExtractKey =
std::__detail::_Select1st; _Equal = std::equal_to<int> _H1 = std::hash<int> _H2
= std::__detail::_Mod_range_hashing; _Hash =
std::__detail::_Default_ranged_hash; _RehashPolicy =
std::__detail::_Prime_rehash_policy; _Traits =
std::__detail::_Hashtable_traits<false, false, true> std::_Hashtable<_Key,
_Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy,
_Traits>::size_type = long unsigned int; std::_Hashtable<_Key, _Value, _Alloc,
_ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>::key_equal =
std::equal_to<int> std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
_H1, _H2, _Hash, _RehashPolicy, _Traits>::allocator_type =
my_allocator<std::pair<const int, double> >]’
/usr/include/c++/4.8/bits/unordered_map.h:189:35: required from
‘std::unordered_map<_Key, _Tp, _Hash, _Pred,
_Alloc>::unordered_map(std::initializer_list<typename std::_Hashtable<_Key,
std::pair<const _Key, _Tp>, _Alloc, std::__detail::_Select1st, _Pred, _Hash,
std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash,
std::__detail::_Prime_rehash_policy,
std::__detail::_Hashtable_traits<std::__not_<std::__and_<std::__is_fast_hash<_Hash>,
std::is_default_constructible<_Hash>, std::is_copy_assignable<_Hash>,
std::__detail::__is_noexcept_hash<_Key, _Hash> > >::value, false, true>
>::value_type>, std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::size_type,
const hasher&, const key_equal&, const allocator_type&) [with _Key = int; _Tp =
double; _Hash = std::hash<int> _Pred = std::equal_to<int> _Alloc =
my_allocator<std::pair<const int, double> > typename std::_Hashtable<_Key,
std::pair<const _Key, _Tp>, _Alloc, std::__detail::_Select1st, _Pred, _Hash,
std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash,
std::__detail::_Prime_rehash_policy,
std::__detail::_Hashtable_traits<std::__not_<std::__and_<std::__is_fast_hash<_Hash>,
std::is_default_constructible<_Hash>, std::is_copy_assignable<_Hash>,
std::__detail::__is_noexcept_hash<_Key, _Hash> > >::value, false, true>
>::value_type = std::pair<const int, double> std::unordered_map<_Key, _Tp,
_Hash, _Pred, _Alloc>::size_type = long unsigned int; std::unordered_map<_Key,
_Tp, _Hash, _Pred, _Alloc>::hasher = std::hash<int> std::unordered_map<_Key,
_Tp, _Hash, _Pred, _Alloc>::key_equal = std::equal_to<int>
std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::allocator_type =
my_allocator<std::pair<const int, double> >]’
main.cpp:17:40: required from here
/usr/include/c++/4.8/bits/hashtable.h:852:19: error: using invalid field
‘std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
_RehashPolicy, _Traits>::_M_bbegin’
_M_rehash_policy()
^
/usr/include/c++/4.8/bits/hashtable.h: In instantiation of
‘std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
_RehashPolicy, _Traits>::__node_base& std::_Hashtable<_Key, _Value, _Alloc,
_ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy,
_Traits>::_M_before_begin() [with _Key = int; _Value = std::pair<const int,
double> _Alloc = my_allocator<std::pair<const int, double> > _ExtractKey =
std::__detail::_Select1st; _Equal = std::equal_to<int> _H1 = std::hash<int> _H2
= std::__detail::_Mod_range_hashing; _Hash =
std::__detail::_Default_ranged_hash; _RehashPolicy =
std::__detail::_Prime_rehash_policy; _Traits =
std::__detail::_Hashtable_traits<false, false, true> std::_Hashtable<_Key,
_Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy,
_Traits>::__node_base = std::__detail::_Hash_node_base]’:
/usr/include/c++/4.8/bits/hashtable.h:1644:23: required from ‘void
std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
_RehashPolicy, _Traits>::clear() [with _Key = int; _Value = std::pair<const
int, double> _Alloc = my_allocator<std::pair<const int, double> > _ExtractKey =
std::__detail::_Select1st; _Equal = std::equal_to<int> _H1 = std::hash<int> _H2
= std::__detail::_Mod_range_hashing; _Hash =
std::__detail::_Default_ranged_hash; _RehashPolicy =
std::__detail::_Prime_rehash_policy; _Traits =
std::__detail::_Hashtable_traits<false, false, true>]’
/usr/include/c++/4.8/bits/hashtable.h:958:13: required from
‘std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
_RehashPolicy, _Traits>::~_Hashtable() [with _Key = int; _Value =
std::pair<const int, double> _Alloc = my_allocator<std::pair<const int, double>
> _ExtractKey = std::__detail::_Select1st; _Equal = std::equal_to<int> _H1 =
std::hash<int> _H2 = std::__detail::_Mod_range_hashing; _Hash =
std::__detail::_Default_ranged_hash; _RehashPolicy =
std::__detail::_Prime_rehash_policy; _Traits =
std::__detail::_Hashtable_traits<false, false, true>]’
/usr/include/c++/4.8/bits/unordered_map.h:97:11: required from here
/usr/include/c++/4.8/bits/hashtable.h:339:26: error: using invalid field
‘std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
_RehashPolicy, _Traits>::_M_bbegin’
{ return _M_bbegin._M_node; }
^
/usr/include/c++/4.8/bits/hashtable.h: In instantiation of ‘void
std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
_RehashPolicy, _Traits>::_M_deallocate_node(std::_Hashtable<_Key, _Value,
_Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy,
_Traits>::__node_type*) [with _Key = int; _Value = std::pair<const int, double>
_Alloc = my_allocator<std::pair<const int, double> > _ExtractKey =
std::__detail::_Select1st; _Equal = std::equal_to<int> _H1 = std::hash<int> _H2
= std::__detail::_Mod_range_hashing; _Hash =
std::__detail::_Default_ranged_hash; _RehashPolicy =
std::__detail::_Prime_rehash_policy; _Traits =
std::__detail::_Hashtable_traits<false, false, true> std::_Hashtable<_Key,
_Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy,
_Traits>::__node_type = std::__detail::_Hash_node<std::pair<const int, double>,
false>]’:
/usr/include/c++/4.8/bits/hashtable.h:763:28: required from ‘void
std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
_RehashPolicy, _Traits>::_M_deallocate_nodes(std::_Hashtable<_Key, _Value,
_Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy,
_Traits>::__node_type*) [with _Key = int; _Value = std::pair<const int, double>
_Alloc = my_allocator<std::pair<const int, double> > _ExtractKey =
std::__detail::_Select1st; _Equal = std::equal_to<int> _H1 = std::hash<int> _H2
= std::__detail::_Mod_range_hashing; _Hash =
std::__detail::_Default_ranged_hash; _RehashPolicy =
std::__detail::_Prime_rehash_policy; _Traits =
std::__detail::_Hashtable_traits<false, false, true> std::_Hashtable<_Key,
_Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy,
_Traits>::__node_type = std::__detail::_Hash_node<std::pair<const int, double>,
false>]’
/usr/include/c++/4.8/bits/hashtable.h:1641:37: required from ‘void
std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
_RehashPolicy, _Traits>::clear() [with _Key = int; _Value = std::pair<const
int, double> _Alloc = my_allocator<std::pair<const int, double> > _ExtractKey =
std::__detail::_Select1st; _Equal = std::equal_to<int> _H1 = std::hash<int> _H2
= std::__detail::_Mod_range_hashing; _Hash =
std::__detail::_Default_ranged_hash; _RehashPolicy =
std::__detail::_Prime_rehash_policy; _Traits =
std::__detail::_Hashtable_traits<false, false, true>]’
/usr/include/c++/4.8/bits/hashtable.h:958:13: required from
‘std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
_RehashPolicy, _Traits>::~_Hashtable() [with _Key = int; _Value =
std::pair<const int, double> _Alloc = my_allocator<std::pair<const int, double>
> _ExtractKey = std::__detail::_Select1st; _Equal = std::equal_to<int> _H1 =
std::hash<int> _H2 = std::__detail::_Mod_range_hashing; _Hash =
std::__detail::_Default_ranged_hash; _RehashPolicy =
std::__detail::_Prime_rehash_policy; _Traits =
std::__detail::_Hashtable_traits<false, false, true>]’
/usr/include/c++/4.8/bits/unordered_map.h:97:11: required from here
/usr/include/c++/4.8/bits/hashtable.h:746:25: error: ‘_M_node_allocator’ was
not declared in this scope
_M_node_allocator().destroy(__n);
^
/usr/include/c++/4.8/bits/hashtable.h: In instantiation of ‘const __node_base&
std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
_RehashPolicy, _Traits>::_M_before_begin() const [with _Key = int; _Value =
std::pair<const int, double> _Alloc = my_allocator<std::pair<const int, double>
> _ExtractKey = std::__detail::_Select1st; _Equal = std::equal_to<int> _H1 =
std::hash<int> _H2 = std::__detail::_Mod_range_hashing; _Hash =
std::__detail::_Default_ranged_hash; _RehashPolicy =
std::__detail::_Prime_rehash_policy; _Traits =
std::__detail::_Hashtable_traits<false, false, true> std::_Hashtable<_Key,
_Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy,
_Traits>::__node_base = std::__detail::_Hash_node_base]’:
/usr/include/c++/4.8/bits/hashtable.h:369:58: required from
‘std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
_RehashPolicy, _Traits>::__node_type* std::_Hashtable<_Key, _Value, _Alloc,
_ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>::_M_begin() const
[with _Key = int; _Value = std::pair<const int, double> _Alloc =
my_allocator<std::pair<const int, double> > _ExtractKey =
std::__detail::_Select1st; _Equal = std::equal_to<int> _H1 = std::hash<int> _H2
= std::__detail::_Mod_range_hashing; _Hash =
std::__detail::_Default_ranged_hash; _RehashPolicy =
std::__detail::_Prime_rehash_policy; _Traits =
std::__detail::_Hashtable_traits<false, false, true> std::_Hashtable<_Key,
_Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy,
_Traits>::__node_type = std::__detail::_Hash_node<std::pair<const int, double>,
false>]’
/usr/include/c++/4.8/bits/hashtable.h:1641:36: required from ‘void
std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
_RehashPolicy, _Traits>::clear() [with _Key = int; _Value = std::pair<const
int, double> _Alloc = my_allocator<std::pair<const int, double> > _ExtractKey =
std::__detail::_Select1st; _Equal = std::equal_to<int> _H1 = std::hash<int> _H2
= std::__detail::_Mod_range_hashing; _Hash =
std::__detail::_Default_ranged_hash; _RehashPolicy =
std::__detail::_Prime_rehash_policy; _Traits =
std::__detail::_Hashtable_traits<false, false, true>]’
/usr/include/c++/4.8/bits/hashtable.h:958:13: required from
‘std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
_RehashPolicy, _Traits>::~_Hashtable() [with _Key = int; _Value =
std::pair<const int, double> _Alloc = my_allocator<std::pair<const int, double>
> _ExtractKey = std::__detail::_Select1st; _Equal = std::equal_to<int> _H1 =
std::hash<int> _H2 = std::__detail::_Mod_range_hashing; _Hash =
std::__detail::_Default_ranged_hash; _RehashPolicy =
std::__detail::_Prime_rehash_policy; _Traits =
std::__detail::_Hashtable_traits<false, false, true>]’
/usr/include/c++/4.8/bits/unordered_map.h:97:11: required from here
/usr/include/c++/4.8/bits/hashtable.h:343:26: error: using invalid field
‘std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
_RehashPolicy, _Traits>::_M_bbegin’
{ return _M_bbegin._M_node; }
^
---
It appears unordered_map uses the allocator directly instead of using its
traits.
More information about the Gcc-bugs
mailing list