2013-05-08 2 views
4

У меня есть этот шаблонный класс:C++ станд :: tr1 :: хэш для шаблонного класса

template <typename T> Thing { ... }; 

, и я хотел бы использовать его в unordered_set:

template <typename T> class Bozo { 
    typedef unordered_set<Thing<T> > things_type; 
    things_type things; 
    ... 
}; 

Теперь класс вещь все, что нужно, кроме хэш-функции. Я хотел бы сделать это родовое, так что я пытаюсь что-то вроде:

namespace std { namespace tr1 { 
    template <typename T> size_t hash<Thing<T> >::operator()(const Thing<T> &t) const { ... } 
}} 

Попытки скомпилировать это с г ++ 4.7 есть она кричала

ожидается инициализатор до того «<»

о

hash<Thing<T> > 

часть декларации. Любые подсказки помогут сохранить несколько оставшихся волос на моей голове.

ответ

6

Невозможно предоставить специализацию всего лишь hash::operator()(const T&); просто специализируйтесь на всем struct hash.

template<typename T> 
struct Thing {}; 

namespace std { namespace tr1 { 
    template<typename T> 
    struct hash<Thing<T>> 
    { 
     size_t operator()(Thing<T> const&) 
     { 
      return 42; 
     } 
    }; 
}} 

Другой способ сделать это, чтобы создать Hasher для Thing, и указать это в качестве второго аргумента шаблона для unordered_set.

template<typename T> 
struct Thing_hasher 
{ 
    size_t operator()(Thing<T>& const) 
    { 
    return 42; 
    } 
}; 

typedef std::unordered_set<Thing<T>, Thing_hasher<T>> things_type; 
+0

Я считаю, что это один из тех редких случаев, когда вы можете написать внутри патезрасе :-) – rwols

+0

@rwols Да, вы имеете право добавить специализаций в 'std' имен – Praetorian

+0

К сожалению, для меня только второй вариант будет работать. Скорее всего, первый будет работать под C++ - 11, но мое приложение должно идти в обоих направлениях. Первый вариант создает конфликты с существующими определениями хеша pre-C++ - 11. Большое спасибо все равно. –

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