1

我正在尝试形成一个 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]

对于第二个错误,显然没有 function<...>::get 成员,但我应该改用什么?

我正在使用 Boost 版本 1.42 和 g++ 4.2.2。谢谢你的帮助。

更新

发布的问题的答案是“你不能”。tr1::function 对象是可散列的(例如,使用 boost::hash),但不能相等比较。如果您想在哈希键中使用函数,请重新考虑方法或找到解决方法。

4

3 回答 3

2

似乎 TR1 特别要求

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

保持 undefined (3.7.2.6),所以至少你必须找到另一种方法来获得平等。此外,我也没有get()在论文中找到对成员方法的任何引用。

于 2011-12-08T01:47:16.043 回答
2

关于 hash_value,我可以回答我自己的问题。这是使用 tr1::function 调用 boost::hash 的正确方法:

friend std::size_t hash_value(Record const & arg)
{
  boost::hash<callback> hasher;
  return hasher(arg.func);
}
于 2011-12-08T18:35:34.460 回答
0

这里这里有一些使用function::target讨论的想法。您可能还需要考虑Boost.Signals库,因为它旨在支持回调注册。

于 2011-12-08T04:37:33.747 回答