2014-03-30 35 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