Сделайте вложенный тип хешируемым для std :: unordered_set

У меня есть шаблонные структуры. struct foo имеет вложенный тип.

template<typename Data>
struct Bar{
};

template<typename Data>
struct Foo {
typedef typename std::pair<Bar<Data>*,Foo<Data>*> Pointers;
std::unordered_set<Pointers> pointers;
};

Я хочу сделать указатели хешируемыми, чтобы они соответствовали std::unordered_set<Pointers>

Я читал здесь:
Как специализироваться на std: : hash :: operator () для пользовательского типа в неупорядоченных контейнерах?
Как правильно хешировать настраиваемую структуру?
boost :: hash_combine
Шаблоны и вложенные классы / структуры

И объедините все знания в этот код:

namespace std {

  template <typename Dara> struct hash< typename Foo<Data>::Pointers>
  {

    size_t operator()(const typename Foo<Data>::Pointers & x) const
    {
        std::size_t seed = 0;
        boost::hash_combine(seed, x.first);
        boost::hash_combine(seed, x.second);
        return seed;
    }
  };
}

На последнем фрагменте кода компилятор выдает ошибку: ошибка: параметры шаблона не используются в частичной специализации: Data в точке здесь: typename Data.

Я пытаюсь удалить данные из шаблона и использовать их так: template <> struct hash< typename Foo::Pointers>, но компилятор говорит мне, что это неправильный тип для шаблона.

Как мне исправить свой код?

С уважением, Таль.


person Tal    schedule 19.11.2015    source источник
comment
Тип указателей не поддерживает хеширование. он не компилируется, а утверждение std::hash как неуспешное.   -  person Tal    schedule 19.11.2015


Ответы (2)


Вы не можете специализироваться на вложенных типах. Компилятор не может понять, на чем вы специализируетесь. Однако вы можете напрямую специализировать std::hash<...> для соответствующего типа:

namespace std {
    template <typename Data>
    struct hash<std::pair<Bar<Data>*,Foo<Data>*>> {
        ...
    }
}

Обратите внимание, что указатели обычно не являются хорошими ключами. Вы можете использовать *x.first и *x.second с hash_combine().

person Dietmar Kühl    schedule 19.11.2015
comment
Спасибо! но я нашел простое решение! :) Я выложу, когда позволю. - person Tal; 19.11.2015
comment
Спасибо за совет с указателем. Думаю, с помощью boost :: hash будет лучше. - person Tal; 19.11.2015

Я нашел более простое решение: добавить boost :: hash:

сделать структуру Foo такой:

template<typename Data>
struct Foo {
typedef typename std::pair<Bar<Data>*,Foo<Data>*> Pointers;
std::unordered_set<Pointers,boost::hash<Pointers> pointers;
};

Прочтите здесь:

person Tal    schedule 19.11.2015