2015-07-03 22 views
5

Come esercizio stavo cercando di vedere se potevo usare SFINAE per creare una specializzazione std::hash per std::pair e std::tuple quando tutti i suoi parametri di modello sono di un tipo senza segno. Ho una piccola esperienza con loro, ma da quello che ho capito la funzione di hash deve essere già stata creata con un typename Enabled = void per aggiungere una specializzazione. Non sono sicuro di dove andare da qui. Ecco un tentativo che non funziona.std :: specializzazione hash con sfinae?

#include <functional> 
#include <type_traits> 
#include <unordered_set> 
#include <utility> 

namespace std { 
template <typename T, typename Enabled = void> 
struct hash<std::pair<T, T>, std::enable_if_t<std::is_unsigned<T>::value>> 
{ 
    size_t operator()(const std::pair<T, T>& x) const 
    { 
     return x; 
    } 
}; 
}; // namespace std 


int 
main(int argc, char ** argv) 
{ 
    std::unordered_set<std::pair<unsigned, unsigned>> test{}; 
    return 0; 
} 

Errore:

hash_sfinae.cpp:7:42: error: default template argument in a class template partial specialization 
template <typename T, typename Enabled = void> 
          ^
hash_sfinae.cpp:8:8: error: too many template arguments for class template 'hash' 
struct hash<std::pair<T, T>, std::enable_if_t<std::is_unsigned<T>::value>> 

Si tratta di quello che mi aspettavo, perché sto cercando di estendere i parametri del modello di hash ... Ma io non sono sicuro che la tecnica per gestire questi casi allora. Qualcuno può aiutarmi a capire?

risposta

9

Non è necessario specializzarsi in std::hash per tipi che non dipendono da un tipo definito dall'utente.

Detto questo, questo hack potrebbe funzionare:

template<class T, class E> 
using first = T; 

template <typename T> 
struct hash<first<std::pair<T, T>, std::enable_if_t<std::is_unsigned<T>::value>>> 
{ 
    size_t operator()(const std::pair<T, T>& x) const 
    { 
     return x; 
    } 
}; 

In realtà, però, non farlo. Scrivi il tuo hasher.

+0

C'è una buona ragione per non specializzare 'std :: hash' per coppie/tuple: mi aspetterei davvero che un hash auto-combinante comparisse in" std "ad un certo punto a breve. – Yakk