2011-11-06 16 views
22

मैं just पाया अपने आप को एक छोटा सा बस एकक्या मानक कंटेनरों के लिए std :: हैश की कोई विशेषज्ञता नहीं है?

std::unordered_set<std::array<int, 16> > test; 

का उपयोग करने में असमर्थ रहा हैरान कर दिया, क्योंकि वहाँ std::array रों के लिए एक std::hash विशेषज्ञता होने के लिए प्रतीत नहीं होता। ऐसा क्यों है? या क्या मुझे बस यह नहीं मिला? यदि वास्तव में कोई नहीं है, तो क्या निम्नलिखित कार्यान्वयन प्रयास को सरल बनाया जा सकता है?

namespace std 
{ 
    template<typename T, size_t N> 
    struct hash<array<T, N> > 
    { 
     typedef array<T, N> argument_type; 
     typedef size_t result_type; 

     result_type operator()(const argument_type& a) const 
     { 
      hash<T> hasher; 
      result_type h = 0; 
      for (result_type i = 0; i < N; ++i) 
      { 
       h = h * 31 + hasher(a[i]); 
      } 
      return h; 
     } 
    }; 
} 

मुझे वास्तव में लगता है कि यह किसी भी तरह से मानक पुस्तकालय का हिस्सा होना चाहिए।

+3

वास्तव में केवल एक नहीं है, केवल 'std :: string' और दोस्तों के पास विशेषाधिकार है। क्या मैं वास्तव में अलोकप्रिय हूं यदि मैंने कहा कि ऐसा इसलिए है क्योंकि मानक डेटा संरचनाओं के संदर्भ में कला की वर्तमान स्थिति की ओर खींचने के लिए सी ++ के प्रयास ने अभी तक पूरी नौकरी नहीं की है? असल में, टेम्पलेट्स के लिए कोई भी 'हैश' विशेषज्ञता नहीं है (और इसके बदले में उनके टेम्पलेट तर्कों को हेशेबल होने की आवश्यकता होगी)। केवल आवश्यक विशेषज्ञताएं अंतर्निर्मित प्रकार और चार कंक्रीट स्ट्रिंग कक्षाओं के लिए हैं। तो मुझे संदेह है कि वहां एक रेखा खींची गई थी। –

+0

@ स्टेव: कौन सी कंक्रीट स्ट्रिंग कक्षाएं? – fredoverflow

+2

'स्ट्रिंग', 'u16string',' u32string', 'wstring' (C++ 11 में 21.6)। मैं कहूंगा कि 'जोड़ी' और 'tuple' अगले उच्चतम प्राथमिकता वाले लक्ष्य होना चाहिए, उसके बाद मानक कंटेनर, उसके बाद हैशबल सदस्यों से बना किसी भी समग्र प्रकार के लिए डिफ़ॉल्ट हैश होना चाहिए। –

उत्तर

11

मुझे यकीन नहीं है कि मानक पुस्तकालय में यह क्यों शामिल नहीं है, लेकिन बूस्ट को हैशबल प्रकारों से बने सभी प्रकार की चीजों के लिए हैशिंग है। इसके लिए महत्वपूर्ण कार्य hash_combine है, जिसे आप boost/functional/hash/hash.hpp से कॉपी करने के लिए स्वागत करते हैं।

hash_combine का उपयोग करके, बूस्ट range_hash (केवल एक श्रेणी के प्रत्येक तत्व के हैंश को जोड़कर), साथ ही जोड़ी और ट्यूपल हैशर प्राप्त करता है। बदले में range_hash हैश को किसी भी पुनरावर्तनीय कंटेनर में उपयोग किया जा सकता है।

+8

हाँ, 'range_hash' लगता है जैसे यह मानक में होना चाहिए। – fredoverflow

11

कोई जवाब नहीं, लेकिन कुछ उपयोगी जानकारी। सी ++ 11 मानक के फ़रवरी मसौदा निर्दिष्ट करता है कि std::hash इन प्रकार के लिए विशेष है:

  • error_code § 19.5.5
  • bitset<N> § 20.5.3
  • unique_ptr<T, D> § 20.7.2.36
  • shared_ptr<T, D> § 20.7.2.36
  • type_index § 20.13.4
  • string § 21.6
  • u16string § 21.6
  • u32string § 21.6
  • wstring § 21.6
  • vector<bool, Allocator> § 23.3.8
  • thread::id § 30.3.1.1

और इन सभी प्रकार: § 20.8.12

template <> struct hash<bool>; 
template <> struct hash<char>; 
template <> struct hash<signed char>; 
template <> struct hash<unsigned char>; 
template <> struct hash<char16_t>; 
template <> struct hash<char32_t>; 
template <> struct hash<wchar_t>; 
template <> struct hash<short>; 
template <> struct hash<unsigned short>; 
template <> struct hash<int>; 
template <> struct hash<unsigned int>; 
template <> struct hash<long>; 
template <> struct hash<long long>; 
template <> struct hash<unsigned long>; 
template <> struct hash<unsigned long long>; 
template <> struct hash<float>; 
template <> struct hash<double>; 
template <> struct hash<long double>; 
template<class T> struct hash<T*>;