Search code examples
c++c++17std-function

std::function as key in associative containers


Is my understanding right that one can not use std::function as a key with neither the ordered, i.e. std::map, std::set, nor unordered associative containers, i.e. std::unordered_map, std::unordered_set?

Background is that I implement a timer driven observer, i.e. in this case the subject. I give the observers a std::function<void(void)> object in order to unsubscribe again. Of course the subject has to house keep which of the callbacks shall be unhooked/deleted when this unsubscription function is invoked.

So naturally I was thinking about using a copy of std::function as key for a std::map or std::unordered_map. In the hope of function pointer like semantics I was hoping of the equal operator, a less or hash implementation for the std::function instantiation. The baffling thing I encountered while reading a reference/the standard is: The operator== and operator!= is not working as expected since they are only comparing to an empty i.e. default constructed function object.

However as I read 23.14.7 and my general understanding, I should be able to use std::function instantiations out of the box in the mentioned containers, since they using std::equal_to instead of directly == right?

Also the identity i.e. the std::equal_to/total order would match two functions objects "pointing" to the same callback as equal, right?


Solution

  • Background is that I implement a timer driven observer, i.e. in this case the subject. I give the observers a std::function object in order to unsubscribe again.

    Don't do that.

    Instead, return an iterator to the container where you stored the function object that the subscriber can use to unsubscribe.


    I should be able to use std::function instantiations out of the box in the mentioned containers, since they using std::equal_to instead of directly == right?

    The generic std::equal_to uses operator == directly. There is no specialisation for std::function. Thus there is no difference between using == and std::equal_to in case of std::function.

    In conclusion: std::function cannot be used as a key in an associative container. And there is no reasonable way to make it work with custom comparison functions either.


    Damn, why the hell is then std::function implementing an std::hash, a total order guaranteed less operator and even arithmatic operators?

    std::function doesn't implement either of those.