Как я могу использовать объект std :: tr1 :: function в ключе unordered_map? - PullRequest
1 голос
/ 08 декабря 2011

Я пытаюсь сформировать std :: tr1 :: unordered_map, где типом ключа является структура, включающая функцию обратного вызова, для которой я использую функцию std :: tr1 :: function. Я сталкиваюсь с двумя проблемами: 1) объект функции не выглядит равноправным, как указано в документации Boost.Function; 2) Я не вижу, как реализовать хеш-функцию, поскольку не могу получить обычный указатель на функцию (или что-то еще, что я мог бы использовать для хеширования) из объекта функции.

Вот пример кода:

#include <boost/functional/hash.hpp>
#include <boost/tr1/functional.hpp>
#include <boost/tr1/unordered_map.hpp>
#include <iostream>

int f(int) {}
typedef std::tr1::function<int(int)> callback;

struct Record
{
  callback func;
  // More members...

  // Requirements for unordered_map key.
  friend bool operator==(Record const & lhs, Record const & rhs)
    { return lhs.func == rhs.func; } // error: ambiguous
  friend std::size_t hash_value(Record const & arg)
    { return boost::hash<void *>(arg.func.get()); } // error: no member get()
};

int main()
{
  std::tr1::unordered_map<Record, int> map;
  Record a = {f};
  map[a] = 0;

  return 0;
}

Вот некоторые подробности о первой ошибке:

test.cpp: In function bool operator==(const Record&, const Record&):
test.cpp:16: error: ambiguous overload for operator== in lhs->Record::func == rhs->Record::func
test.cpp:16: note: candidates are: operator==(void (boost::function1<int, int>::dummy::*)(), void (boost::function1<int, int>::dummy::*)()) <built-in>
<root>/boost/function/function_template.hpp:1024: note:                 void boost::operator==(const boost::function1<R, T0>&, const boost::function1<R, T0>&) [with R = int, T0 = int]

Для второй ошибки, очевидно, нет функции <...> :: get member, но что мне вместо этого использовать?

Я использую Boost версии 1.42 и g ++ 4.2.2. Спасибо за любую помощь.

Обновление

Ответ на опубликованный вопрос: «Вы не можете». Объекты tr1 :: function можно хэшировать (например, используя boost :: hash), но они не могут быть сравнимы по равенству. Если вы хотите использовать функцию в хэш-ключе, переосмыслите подход или найдите обходной путь.

Ответы [ 3 ]

2 голосов
/ 08 декабря 2011

Я могу ответить на свой вопрос относительно hash_value. Это правильный способ вызова boost :: hash с помощью tr1 :: function:

friend std::size_t hash_value(Record const & arg)
{
  boost::hash<callback> hasher;
  return hasher(arg.func);
}
2 голосов
/ 08 декабря 2011

Казалось бы, TR1 специально требует, чтобы

template<class Function2> bool operator==(const function<Function2>&);
template<class Function2> bool operator!=(const function<Function2>&);

остаются неопределенными (3.7.2.6) , поэтому, по крайней мере, вам нужно будет найти другой способ получить равенство. Более того, я не нахожу в статье ни ссылки на get() метод члена.

0 голосов
/ 08 декабря 2011

Есть некоторые идеи использования function::target, обсуждаемые здесь и здесь . Вы также можете рассмотреть библиотеку Boost.Signals , так как она предназначена для поддержки регистрации обратных вызовов.

...