Определение пользовательской хэш-функции и функции равенства для unordered_map

Я пытаюсь определить тип unordered_map, который имеет пользовательскую хеш-функцию и функцию сравнения равенств. Прототипы функций этих функций следующие:

//set<Vertex3DXT*> is the type of the key; Cell3DXT* is the type of the value
size_t VertexSetHashFunction(set<Vertex3DXT*> vertexSet); //hash function
bool SetEqual(set<Vertex3DXT*> a, set<Vertex3DXT*> b); //equality

Я объявляю эти прототипы функций, а затем я пытаюсь объявить тип следующим образом:

typedef std::tr1::unordered_map<set<Vertex3DXT*>, Cell3DXT*, VertexSetHashFunction, SetEqual> CellDatabaseMapType;

Но он говорит, что VertexSetHashFunction и SetEqual не являются допустимыми аргументами типа шаблона. Документация сбивает с толку, потому что она не говорит точно, какой тип аргументов шаблона должен быть - я просто должен дать ему функцию, как я здесь, или есть какой-то другой объект, который инкапсулирует функцию (потому что документация говорит о "объекте функции хеш-функции" )?

Ответ 1

Эти функции должны быть объявлены как оператор() в классе, к сожалению. Вот так:

class VertexSetHashFunction {
  public:
    ::std::size_t operator ()(const ::std::set<Vertex3DXT*> &vertexSet) const;
};
class SetEqual {
  public:
    bool operator ()(const ::std::set<Vertex3DXT*> &a, const ::std::set<Vertex3DXT*> &b) const;
};

Вам не нужно изменять аргументы как ссылки на const, но я бы очень рекомендовал его. Создание копии:: std:: set относительно дорого, и вы не должны этого делать, если вам абсолютно не нужно.

Конечная константа только потому, что оператор фактически не модифицирует состояние класса, в основном потому, что его нет. Просто приятно сказать это явно.

В качестве альтернативы вы можете определить свою собственную специализацию шаблона:: std:: hash. Я бы рекомендовал это, если есть один стандартный способ, которым вы хотите, чтобы этот конкретный набор хэшировал, потому что этот шаблон используется по умолчанию, если вы не предоставляете хэш-функцию для unordered_map или unordered_set и всего остального, что требует хеш-функции.

Ответ 2

Вам нужны функторы.

struct VertexSetHashFunction {
    size_t operator() (const set<Vertex3DXT*>& vertexSet) const { return /*whatever*/; }
};

struct SetEqual {
    bool operator() (const set<Vertex3DXT*>& a, const set<Vertex3DXT*>& b) const { return /*whatever*/; }
};