C++ std::函数作为关联容器中的键

C++ std::函数作为关联容器中的键,c++,c++17,std-function,C++,C++17,Std Function,我的理解是否正确,即不能将std::function用作既没有顺序的键,即std::map,std::set,也没有无序的关联容器,即std::unordered\u map,std::unordered\u set 背景是我实现了一个定时器驱动的观察者,即在本例中的主体。我给观察者一个std::function对象,以便再次取消订阅。当然,主体必须保留调用此取消订阅功能时应取消/删除哪些回调 因此,我自然会考虑使用std::function的副本作为std::map或std::unordere

我的理解是否正确,即不能将
std::function
用作既没有顺序的键,即
std::map
std::set
,也没有无序的关联容器,即
std::unordered\u map
std::unordered\u set

背景是我实现了一个定时器驱动的观察者,即在本例中的主体。我给观察者一个
std::function
对象,以便再次取消订阅。当然,主体必须保留调用此取消订阅功能时应取消/删除哪些回调

因此,我自然会考虑使用
std::function
的副本作为
std::map
std::unordered_map
的键。为了实现类似函数指针的语义,我希望使用equal运算符,即
std::function
实例化的less或hash实现。在阅读参考资料/标准时,我遇到的令人困惑的事情是:
操作符==
操作符=未按预期工作,因为它们仅与空(即默认构造的函数对象)进行比较

然而,当我阅读23.14.7和我的一般理解时,我应该能够在提到的容器中开箱即用地使用
std::function
实例化,因为它们使用
std::equal_to
而不是直接
=
对吗

此外,标识(即
std::equal_to
/total顺序)将匹配两个函数对象“指向”同一个回调作为equal,对吗

背景是我实现了一个定时器驱动的观察者,即在本例中的主体。我给观察者一个std::function对象,以便再次取消订阅

不要那样做

相反,将迭代器返回到存储订阅者可以用来取消订阅的函数对象的容器中


我应该能够在提到的容器中开箱即用地使用std::函数实例化,因为它们使用std::equal_to而不是直接==对吗

通用的
std::equal_to
直接使用运算符
=
std::function
没有专门化。因此,在使用
std::function
的情况下,使用
==
std::equal_to
之间没有区别

总之:
std::function
不能用作关联容器中的键。而且也没有合理的方法使其与自定义比较函数一起工作


该死的,为什么std::函数要实现std::hash,一个总的顺序保证较少的运算符,甚至算术运算符


std::function
不能实现这两种功能。

我认为
std::equal_to
无论如何都会使用默认的
=
,而且由于
==
只能与
std::nullptr\u t
类型一起工作,所以您无法执行您描述的操作。@Superlokus您在哪里看到这些东西的?我在(散列、less和算术运算符)中找不到它们中的任何一个。这不是直接可行的,因为我必须转换调用者的线程/生命周期/同步边界,即我的主题使用boost::asio运行,并且有自己的线程,调用者试图从Qt GUI线程取消订阅,或者通过javascript GUI线程的NAPI,再加上boost::asio::strand上的同步。@Superlokkus不清楚如何使用
std::function
作为密钥来解决这个问题。只是我可以省略一个id来进行内部管理。不过,请将您的答案集中在在在ass.容器中使用std::function的一般问题上。似乎anwser是否定的,没有人可以使用它们,尽管这样的代码格式良好,但它将无法使用。为了让您更好地了解:取消订阅回调/函数对象当然会包含先同步实际取消订阅的指令,也就是说,只需在包含的io_上下文中发布一条给定的链,它删除内部容器中的观察回调。