2011-12-24 5 views
0

У меня есть unordered_map и не может сравнивать итераторы, возвращаемые find() и end(). Вот ситуация:C++: unordered_map, итераторы не сопоставимы

unordered_map<IpAddressPort, uint32, IpAddressPortKey> current_sequence_numbers; 

... 

if (current_sequence_numbers.find(address) == current_sequence_numbers.end()) { 
    ... 
} 

Где IpAddressPort лишь некоторые struct и IpAddressPortKey выглядит следующим образом

struct IpAddressPortKey { 
    inline size_t operator()(const IpAddressPort &p) const { 
     return (p.type << 24 | p.addr_ipv4 | p.addr_ipv6.w1 | p.addr_ipv6.w2 
      | p.addr_ipv6.w3 | p.addr_ipv6.w4 | p.port); 
    } 
}; 

при сравнении в if блоке дает эту ошибку:

/usr/include/c++/4.6/bits/hashtable.h:892:2: instantiated from ‘std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::_Node* std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::_M_find_node(std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::_Node*, const key_type&, typename std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::_Hash_code_type) const [with _Key = reload::IpAddressPort, _Value = std::pair<const reload::IpAddressPort, unsigned int>, _Allocator = std::allocator<std::pair<const reload::IpAddressPort, unsigned int> >, _ExtractKey = std::_Select1st<std::pair<const reload::IpAddressPort, unsigned int> >, _Equal = std::equal_to<reload::IpAddressPort>, _H1 = reload::IpAddressPortKey, _H2 = std::__detail::_Mod_range_hashing, _Hash = std::__detail::_Default_ranged_hash, _RehashPolicy = std::__detail::_Prime_rehash_policy, bool __cache_hash_code = false, bool __constant_iterators = false, bool __unique_keys = true, std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::_Node = std::__detail::_Hash_node<std::pair<const reload::IpAddressPort, unsigned int>, false>, std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::key_type = reload::IpAddressPort, typename std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::_Hash_code_type = unsigned int]’ 
/usr/include/c++/4.6/bits/hashtable.h:760:61: instantiated from ‘std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::iterator std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::find(const key_type&) [with _Key = reload::IpAddressPort, _Value = std::pair<const reload::IpAddressPort, unsigned int>, _Allocator = std::allocator<std::pair<const reload::IpAddressPort, unsigned int> >, _ExtractKey = std::_Select1st<std::pair<const reload::IpAddressPort, unsigned int> >, _Equal = std::equal_to<reload::IpAddressPort>, _H1 = reload::IpAddressPortKey, _H2 = std::__detail::_Mod_range_hashing, _Hash = std::__detail::_Default_ranged_hash, _RehashPolicy = std::__detail::_Prime_rehash_policy, bool __cache_hash_code = false, bool __constant_iterators = false, bool __unique_keys = true, std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::iterator = std::__detail::_Hashtable_iterator<std::pair<const reload::IpAddressPort, unsigned int>, false, false>, std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::key_type = reload::IpAddressPort]’ 
link_management.cpp:134:51: instantiated from here 
/usr/include/c++/4.6/bits/stl_function.h:209:23: error: no match for ‘operator==’ in ‘__x == __y’ 
/usr/include/c++/4.6/bits/stl_function.h:209:23: note: candidates are: 
/usr/include/c++/4.6/bits/postypes.h:218:5: note: template<class _StateT> bool std::operator==(const std::fpos<_StateT>&, const std::fpos<_StateT>&) 
/usr/include/c++/4.6/bits/stl_pair.h:201:5: note: template<class _T1, class _T2> constexpr bool std::operator==(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&) 
/usr/include/c++/4.6/bits/stl_iterator.h:285:5: note: template<class _Iterator> bool std::operator==(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_Iterator>&) 
/usr/include/c++/4.6/bits/stl_iterator.h:335:5: note: template<class _IteratorL, class _IteratorR> bool std::operator==(const std::reverse_iterator<_IteratorL>&, const std::reverse_iterator<_IteratorR>&) 
/usr/include/c++/4.6/bits/stl_iterator.h:1025:5: note: template<class _IteratorL, class _IteratorR> bool std::operator==(const std::move_iterator<_IteratorL>&, const std::move_iterator<_IteratorR>&) 
/usr/include/c++/4.6/bits/stl_iterator.h:1031:5: note: template<class _Iterator> bool std::operator==(const std::move_iterator<_Iterator>&, const std::move_iterator<_Iterator>&) 
/usr/include/c++/4.6/bits/allocator.h:122:5: note: template<class _T1, class _T2> bool std::operator==(const std::allocator<_T1>&, const std::allocator<_T2>&) 
/usr/include/c++/4.6/bits/allocator.h:127:5: note: template<class _Tp> bool std::operator==(const std::allocator<_Tp1>&, const std::allocator<_Tp1>&) 
/usr/include/c++/4.6/bits/basic_string.h:2427:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator==(const std::basic_string<_CharT, _Traits, _Alloc>&, const std::basic_string<_CharT, _Traits, _Alloc>&) 
/usr/include/c++/4.6/bits/basic_string.h:2434:5: note: template<class _CharT> typename __gnu_cxx::__enable_if<std::__is_char<_Tp>::__value, bool>::__type std::operator==(const std::basic_string<_CharT>&, const std::basic_string<_CharT>&) 
/usr/include/c++/4.6/bits/basic_string.h:2448:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator==(const _CharT*, const std::basic_string<_CharT, _Traits, _Alloc>&) 
/usr/include/c++/4.6/bits/basic_string.h:2460:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator==(const std::basic_string<_CharT, _Traits, _Alloc>&, const _CharT*) 
/usr/include/c++/4.6/bits/streambuf_iterator.h:194:5: note: template<class _CharT, class _Traits> bool std::operator==(const std::istreambuf_iterator<_CharT, _Traits>&, const std::istreambuf_iterator<_CharT, _Traits>&) 
/usr/include/c++/4.6/bits/unordered_map.h:201:5: note: template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, bool __cache_hash_code> bool std::operator==(const std::__unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc, __cache_hash_code>&, const std::__unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc, __cache_hash_code>&) 
/usr/include/c++/4.6/bits/unordered_map.h:219:5: note: template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, bool __cache_hash_code> bool std::operator==(const std::__unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc, __cache_hash_code>&, const std::__unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc, __cache_hash_code>&) 
/usr/include/c++/4.6/bits/unordered_map.h:384:5: note: template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> bool std::operator==(const std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>&, const std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>&) 
/usr/include/c++/4.6/bits/unordered_map.h:396:5: note: template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> bool std::operator==(const std::unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>&, const std::unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>&) 
/usr/include/c++/4.6/bits/stl_list.h:275:5: note: template<class _Val> bool std::operator==(const std::_List_iterator<_Tp>&, const std::_List_const_iterator<_Val>&) 
/usr/include/c++/4.6/bits/stl_list.h:1564:5: note: template<class _Tp, class _Alloc> bool std::operator==(const std::list<_Tp, _Alloc>&, const std::list<_Tp, _Alloc>&) 
/usr/include/c++/4.6/bits/stl_deque.h:246:5: note: template<class _Tp, class _Ref, class _Ptr> bool std::operator==(const std::_Deque_iterator<_Tp, _Ref, _Ptr>&, const std::_Deque_iterator<_Tp, _Ref, _Ptr>&) 
/usr/include/c++/4.6/bits/stl_deque.h:253:5: note: template<class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR> bool std::operator==(const std::_Deque_iterator<_Tp, _RefL, _PtrL>&, const std::_Deque_iterator<_Tp, _RefR, _PtrR>&) 
/usr/include/c++/4.6/bits/stl_deque.h:1917:5: note: template<class _Tp, class _Alloc> bool std::operator==(const std::deque<_Tp, _Alloc>&, const std::deque<_Tp, _Alloc>&) 
/usr/include/c++/4.6/bits/stl_tree.h:309:5: note: template<class _Val> bool std::operator==(const std::_Rb_tree_iterator<_Tp>&, const std::_Rb_tree_const_iterator<_Val>&) 
/usr/include/c++/4.6/bits/stl_tree.h:846:5: note: template<class _Key, class _Val, class _KeyOfValue, class _Compare, class _Alloc> bool std::operator==(const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&, const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&) 
/usr/include/c++/4.6/bits/stl_map.h:877:5: note: template<class _Key, class _Tp, class _Compare, class _Alloc> bool std::operator==(const std::map<_Key, _Tp, _Compare, _Alloc>&, const std::map<_Key, _Tp, _Compare, _Alloc>&) 
/usr/include/c++/4.6/bits/stl_multimap.h:795:5: note: template<class _Key, class _Tp, class _Compare, class _Alloc> bool std::operator==(const std::multimap<_Key, _Tp, _Compare, _Alloc>&, const std::multimap<_Key, _Tp, _Compare, _Alloc>&) 
/usr/include/c++/4.6/bits/stl_set.h:696:5: note: template<class _Key, class _Compare, class _Alloc> bool std::operator==(const std::set<_Key, _Compare, _Alloc>&, const std::set<_Key, _Compare, _Alloc>&) 
/usr/include/c++/4.6/bits/stl_multiset.h:679:5: note: template<class _Key, class _Compare, class _Alloc> bool std::operator==(const std::multiset<_Key, _Compare, _Alloc>&, const std::multiset<_Key, _Compare, _Alloc>&) 
/usr/include/c++/4.6/bits/stl_vector.h:1273:5: note: template<class _Tp, class _Alloc> bool std::operator==(const std::vector<_Tp, _Alloc>&, const std::vector<_Tp, _Alloc>&) 

Любая идея, что может вызвать это?

+0

Можете ли вы предоставить остальную часть ошибки? Это явно просто в реализации stl и даже не полная ошибка для этой строки, я не думаю. – lefticus

+0

@lefticus: done – aRestless

ответ

3

Похоже, что вы не определили operator==() для класса IpAddressPort. Вы можете определить operator== или определить функтор эквити и предоставить его в качестве аргумента 4-го шаблона

+0

Как это может быть причиной сравнения итераторов (а не структур, на которые они указывают)? 'end()' даже не указывает на действительную структуру, поскольку это индикатор того, что элемент не может быть найден. – aRestless

+0

Этот ответ правильный, я сам его тестировал. Я не могу найти ничего в стандарте, специально говоря, что unordered_map требует, чтобы ключи были равноценными. Я знаю, что ключи в std :: map должны быть менее сопоставимыми (что имеет смысл, поскольку они упорядочены). – lefticus

+0

@lefticus: Очевидно, что неупорядоченная карта требует сравнения сравнений элементов для реализации хеш-таблицы. Это рассуждение не может быть явным в стандарте, но, безусловно, сопоставимое с равенством требование. –

Смежные вопросы