2014-03-30 37 views
4

我想在我的应用程序中建立链表的列表。该列表将包含唯一的IP地址,并且对于每个IP地址,我都有一个应用程序列表。我试图用unordered_map采取的boost ::升压:: ASIO ::知识产权来构建它::地址作为重点和std ::列表作为值:unordered_map与IP地址作为键

#include <boost/unordered/unordered_map.hpp> 
#include <iostream> 
#include <list> 

using namespace boost::asio::ip; 
using namespace std; 

typedef int  ApplicationID; 
typedef address IPAddress; 
typedef list <ApplicationID> APP_LIST; 
typedef boost::unordered::unordered_map <IPAddress, APP_LIST> USER_MAP; 

USER_MAP user_map; 

后来我试图让该列表相关联与IP地址如下:

APP_LIST *list = &user_map[ip]; 

但我得到的编译错误,所以你可以请注明什么问题?

  1. 是否可以使用Boost:IPaddress作为关键功能?

  2. 另一个问题是有可能使用char [some_size]作为关键值?

错误输出:

In file included from /boost/functional/hash/hash.hpp:535:0, 
       from /boost/functional/hash.hpp:6, 
       from /boost/unordered/unordered_map.hpp:21, 
       from ipc_module.cpp:18: 
/boost/functional/hash/extensions.hpp: In member function ‘std::size_t boost::hash<T>::operator()(const T&) const [with T = boost::asio::ip::address, std::size_t = long unsigned int]’: 
/boost/unordered/detail/unique.hpp:331:55: instantiated from ‘boost::unordered::detail::table_impl<Types>::value_type& boost::unordered::detail::table_impl<Types>::operator[](const key_type&) [with Types = boost::unordered::detail::map<std::allocator<std::pair<const boost::asio::ip::address, std::list<int> > >, boost::asio::ip::address, std::list<int>, boost::hash<boost::asio::ip::address>, std::equal_to<boost::asio::ip::address> >, boost::unordered::detail::table_impl<Types>::value_type = std::pair<const boost::asio::ip::address, std::list<int> >, boost::unordered::detail::table_impl<Types>::key_type = boost::asio::ip::address]’ 
/boost/unordered/unordered_map.hpp:1192:26: instantiated from ‘boost::unordered::unordered_map<K, T, H, P, A>::mapped_type& boost::unordered::unordered_map<K, T, H, P, A>::operator[](const key_type&) [with K = boost::asio::ip::address, T = std::list<int>, H = boost::hash<boost::asio::ip::address>, P = std::equal_to<boost::asio::ip::address>, A = std::allocator<std::pair<const boost::asio::ip::address, std::list<int> > >, boost::unordered::unordered_map<K, T, H, P, A>::mapped_type = std::list<int>, boost::unordered::unordered_map<K, T, H, P, A>::key_type = boost::asio::ip::address]’ 
ipc_module.cpp:175:40: instantiated from here 
/boost/functional/hash/extensions.hpp:176:34: error: no matching function for call to ‘hash_value(const boost::asio::ip::address&)’ 
/boost/functional/hash/extensions.hpp:176:34: note: candidates are: 
/boost/smart_ptr/shared_ptr.hpp:708:33: note: template<class T> std::size_t boost::hash_value(const boost::shared_ptr<T>&) 
/boost/functional/hash/hash.hpp:144:24: note: std::size_t boost::hash_value(bool) 
/boost/functional/hash/hash.hpp:144:24: note: no known conversion for argument 1 from ‘const boost::asio::ip::address’ to ‘bool’ 
/boost/functional/hash/hash.hpp:149:24: note: std::size_t boost::hash_value(char) 
/boost/functional/hash/hash.hpp:149:24: note: no known conversion for argument 1 from ‘const boost::asio::ip::address’ to ‘char’ 
/boost/functional/hash/hash.hpp:154:24: note: std::size_t boost::hash_value(unsigned char) 
/boost/functional/hash/hash.hpp:154:24: note: no known conversion for argument 1 from ‘const boost::asio::ip::address’ to ‘unsigned char’ 
/boost/functional/hash/hash.hpp:159:24: note: std::size_t boost::hash_value(signed char) 
/boost/functional/hash/hash.hpp:159:24: note: no known conversion for argument 1 from ‘const boost::asio::ip::address’ to ‘signed char’ 
/boost/functional/hash/hash.hpp:164:24: note: std::size_t boost::hash_value(short int) 
/boost/functional/hash/hash.hpp:164:24: note: no known conversion for argument 1 from ‘const boost::asio::ip::address’ to ‘short int’ 
/boost/functional/hash/hash.hpp:169:24: note: std::size_t boost::hash_value(short unsigned int) 
/boost/functional/hash/hash.hpp:169:24: note: no known conversion for argument 1 from ‘const boost::asio::ip::address’ to ‘short unsigned int’ 
/boost/functional/hash/hash.hpp:174:24: note: std::size_t boost::hash_value(int) 
/boost/functional/hash/hash.hpp:174:24: note: no known conversion for argument 1 from ‘const boost::asio::ip::address’ to ‘int’ 
/boost/functional/hash/hash.hpp:179:24: note: std::size_t boost::hash_value(unsigned int) 
/boost/functional/hash/hash.hpp:179:24: note: no known conversion for argument 1 from ‘const boost::asio::ip::address’ to ‘unsigned int’ 
/boost/functional/hash/hash.hpp:184:24: note: std::size_t boost::hash_value(long int) 
/boost/functional/hash/hash.hpp:184:24: note: no known conversion for argument 1 from ‘const boost::asio::ip::address’ to ‘long int’ 
/boost/functional/hash/hash.hpp:189:24: note: std::size_t boost::hash_value(long unsigned int) 
/boost/functional/hash/hash.hpp:189:24: note: no known conversion for argument 1 from ‘const boost::asio::ip::address’ to ‘long unsigned int’ 
/boost/functional/hash/hash.hpp:195:24: note: std::size_t boost::hash_value(wchar_t) 
/boost/functional/hash/hash.hpp:195:24: note: no known conversion for argument 1 from ‘const boost::asio::ip::address’ to ‘wchar_t’ 
/boost/functional/hash/hash.hpp:202:24: note: std::size_t boost::hash_value(boost::long_long_type) 
/boost/functional/hash/hash.hpp:202:24: note: no known conversion for argument 1 from ‘const boost::asio::ip::address’ to ‘boost::long_long_type {aka long long int}’ 
/boost/functional/hash/hash.hpp:207:24: note: std::size_t boost::hash_value(boost::ulong_long_type) 
/boost/functional/hash/hash.hpp:207:24: note: no known conversion for argument 1 from ‘const boost::asio::ip::address’ to ‘boost::ulong_long_type {aka long long unsigned int}’ 
/boost/functional/hash/hash.hpp:215:36: note: template<class T> std::size_t boost::hash_value(T* const&) 
/boost/functional/hash/hash.hpp:308:24: note: template<class T, unsigned int N> std::size_t boost::hash_value(const T (&)[N]) 
/boost/functional/hash/hash.hpp:314:24: note: template<class T, unsigned int N> std::size_t boost::hash_value(T (&)[N]) 
/boost/functional/hash/hash.hpp:327:24: note: std::size_t boost::hash_value(float) 
/boost/functional/hash/hash.hpp:327:24: note: no known conversion for argument 1 from ‘const boost::asio::ip::address’ to ‘float’ 
/boost/functional/hash/hash.hpp:332:24: note: std::size_t boost::hash_value(double) 
/boost/functional/hash/hash.hpp:332:24: note: no known conversion for argument 1 from ‘const boost::asio::ip::address’ to ‘double’ 
/boost/functional/hash/hash.hpp:337:24: note: std::size_t boost::hash_value(long double) 
/boost/functional/hash/hash.hpp:337:24: note: no known conversion for argument 1 from ‘const boost::asio::ip::address’ to ‘long double’ 
/boost/functional/hash/hash.hpp:321:24: note: template<class Ch, class A> std::size_t boost::hash_value(const std::basic_string<Ch, std::char_traits<_CharT>, A>&) 
/boost/functional/hash/hash.hpp:343:24: note: std::size_t boost::hash_value(std::type_index) 
/boost/functional/hash/hash.hpp:343:24: note: no known conversion for argument 1 from ‘const boost::asio::ip::address’ to ‘std::type_index’ 
/boost/functional/hash/extensions.hpp:54:17: note: template<class A, class B> std::size_t boost::hash_value(const std::pair<_T1, _T2>&) 
/boost/functional/hash/extensions.hpp:63:17: note: template<class T, class A> std::size_t boost::hash_value(const std::vector<_Tp, _Alloc>&) 
/boost/functional/hash/extensions.hpp:69:17: note: template<class T, class A> std::size_t boost::hash_value(const std::list<_Tp, _Alloc>&) 
/boost/functional/hash/extensions.hpp:75:17: note: template<class T, class A> std::size_t boost::hash_value(const std::deque<_Tp, _Alloc>&) 
/boost/functional/hash/extensions.hpp:81:17: note: template<class K, class C, class A> std::size_t boost::hash_value(const std::set<_Key, _Compare, _Alloc>&) 
/boost/functional/hash/extensions.hpp:87:17: note: template<class K, class C, class A> std::size_t boost::hash_value(const std::multiset<_Key, _Compare, _Alloc>&) 
/boost/functional/hash/extensions.hpp:93:17: note: template<class K, class T, class C, class A> std::size_t boost::hash_value(const std::map<_Key, _Tp, _Compare, _Alloc>&) 
/boost/functional/hash/extensions.hpp:99:17: note: template<class K, class T, class C, class A> std::size_t boost::hash_value(const std::multimap<_Key, _Tp, _Compare, _Alloc>&) 
/boost/functional/hash/extensions.hpp:105:17: note: template<class T> std::size_t boost::hash_value(const std::complex<_Tp>&) 
/boost/functional/hash/extensions.hpp:177:9: warning: control reaches end of non-void function [-Wreturn-type] 
/boost/asio/error.hpp: At global scope: 
/boost/asio/error.hpp:244:45: warning: ‘boost::asio::error::system_category’ defined but not used [-Wunused-variable] 
/boost/asio/error.hpp:246:45: warning: ‘boost::asio::error::netdb_category’ defined but not used [-Wunused-variable] 
/boost/asio/error.hpp:248:45: warning: ‘boost::asio::error::addrinfo_category’ defined but not used [-Wunused-variable] 
/boost/asio/error.hpp:250:45: warning: ‘boost::asio::error::misc_category’ defined but not used [-Wunused-variable] 
+0

可能要格式化你的代码,我知道它的很多。请考虑周到。 – Idris

+0

@收缩我减少了输出,我相信我保留的就足够了。 – IoT

+0

虽然它仍然没有格式正确。人们似乎忽略了格式不正确的问题。 – Idris

回答

5

下面是我在对ip::address的类接口进行简要检查后得出的结论。

我想说明的是,使用它非常浪费。特别是如果你碰巧知道所有地址都是ipv4,例如那么我宁愿输入ulong

namespace boost 
{ 
    template <> 
     struct hash<IPAddress> 
     { 
      size_t operator()(IPAddress const& v) const { 
       if (v.is_v4()) 
        return v.to_v4().to_ulong(); 
       if (v.is_v6()) 
       { 
        auto const& range = v.to_v6().to_bytes(); 
        return hash_range(range.begin(), range.end()); 
       } 
       if (v.is_unspecified()) 
       { 
        // guaranteed to be random: chosen by fair dice roll 
        return static_cast<size_t>(0x4751301174351161ul); 
       } 
       return hash_value(v.to_string()); 
      } 
     }; 
} 

看到它Live on Coliru

#include <boost/asio.hpp> 
#include <boost/unordered/unordered_map.hpp> 
#include <iostream> 
#include <list> 

typedef int             ApplicationID; 
typedef boost::asio::ip::address        IPAddress; 
typedef std::list<ApplicationID>        APP_LIST; 
typedef boost::unordered::unordered_map<IPAddress, APP_LIST> USER_MAP; 

namespace boost 
{ 
    template <> 
     struct hash<IPAddress> 
     { 
      size_t operator()(IPAddress const& v) const { 
       if (v.is_v4()) 
        return v.to_v4().to_ulong(); 
       if (v.is_v6()) 
       { 
        auto const& range = v.to_v6().to_bytes(); 
        return hash_range(range.begin(), range.end()); 
       } 
       if (v.is_unspecified()) 
        return 0x4751301174351161ul; 
       return hash_value(v.to_string()); 
      } 
     }; 
} 

int main() 
{ 
    USER_MAP map; 
    map.insert({ {}, {} }); 
} 
+0

+1,@sehe非常感谢您的回答,但我的问题为什么不直接使用'return hash_value(v.to_string());' 对于第二个问题,是否可以使用char [some_size ]作为unordered_map中的关键值? – IoT

+0

@ HA-AS 1st:效率(事实上,我只是把它当作“鸡”来使用,以免我错过了某些领域的知识,如果你有一个'assert(!“unreachable”)'大胆)。第二:不,但是如果你为它写一个散列函数:[见coliru](http://coliru.stacked-crooked.com/a/cfbc9797b8eec857) – sehe

+0

@ HA-AS Mmm。其实,罢工。* [GCC接受它](http://coliru.stacked-crooked.com/a/d5398fd20e3ce864)*,但我认为原始数组不能用作映射键。所以,青睐'std :: array'或'boost :: array':http://coliru.stacked-crooked.com/a/c51aca6d945d2d25 – sehe

2

,如果你写的名称IP地址的哈希函数,它将正常工作。

+0

谢谢,但你能给我一个例子如何做到这一点,对于非字符串数据类型 – IoT

+0

http://www.boost.org/doc/libs/1_55_0/doc/html/hash/custom.html – Petter

+0

+1原则上正确。我认为提供单线答案通常不会有帮助。在评论中放弃这些智慧块,这是一种礼节。 – sehe