简体   繁体   English

如何在unordered_map的密钥中使用std :: tr1 :: function对象?

[英]How can I use a std::tr1::function object in a key to unordered_map?

I'm trying to form a std::tr1::unordered_map where the key type is a struct that includes a callback function, for which I'm using std::tr1::function. 我正在尝试形成一个std :: tr1 :: unordered_map,其中键类型是一个包含回调函数的结构,我正在使用std :: tr1 :: function。 I'm running into two problems: 1) the function object does not appear to be equality comparable, as the Boost.Function documentation indicates; 我遇到了两个问题:1)函数对象似乎没有可比性,正如Boost.Function文档所示; 2) I don't see how to implement the hash function, since I can't get a regular function pointer (or something else I could use for hashing) from the function object. 2)我没有看到如何实现哈希函数,因为我无法从函数对象中获得常规函数指针(或者我可以用于散列的其他东西)。

Here's the example code: 这是示例代码:

#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;
}

Here's some detail on the first error : 这是第一个错误的一些细节:

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]

For the second error, obviously there's no function<...>::get member, but what should I use instead? 对于第二个错误,显然没有函数<...> :: get member,但我应该使用什么呢?

I'm using Boost version 1.42 and g++ 4.2.2. 我正在使用Boost版本1.42和g ++ 4.2.2。 Thanks for any help. 谢谢你的帮助。

Update 更新

The answer to the posted question is "you can't." 发布的问题的答案是“你不能。” tr1::function objects are hashable (eg, using boost::hash), but are not equality comparable. tr1 :: function对象是可散列的(例如,使用boost :: hash),但不是相等的。 If you want to use a function in the hash key, rethink the approach or find a workaround. 如果要在哈希键中使用函数,请重新考虑该方法或找到变通方法。

It would seem that TR1 specifically requires that 似乎TR1特别要求这样做

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

remain undefined (3.7.2.6) , so at the very least you'd have to find another way to get equality. 保持未定义(3.7.2.6) ,所以至少你必须找到另一种获得平等的方法。 Furthermore, I'm not finding any reference to a get() member method in the paper either. 此外,我也没有在论文中找到任何对get()成员方法的引用。

I can answer my own question as regards to the hash_value. 关于hash_value,我可以回答我自己的问题。 This is the correct way to call boost::hash with a tr1::function: 这是使用tr1 :: function调用boost :: hash的正确方法:

friend std::size_t hash_value(Record const & arg)
{
  boost::hash<callback> hasher;
  return hasher(arg.func);
}

There are some ideas using function::target discussed here and here . 这里这里讨论了使用function::target一些想法。 You may also want to consider the Boost.Signals library as it's designed to support registration of callbacks. 您可能还需要考虑Boost.Signals库,因为它旨在支持回调注册。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM