How can I compare two C++11 std::function
s with operator==
, and return true
if both of said function
s refer to the same function pointer?

- 2,025
- 1
- 24
- 48
-
1Then what does `std::function::target` do? – JesseTG Dec 30 '13 at 04:50
-
2Funnily enough, `boost::function` allows more equality checking than `std::function` AFAIK. – chris Dec 30 '13 at 05:01
-
Appears to be a duplicate of: https://stackoverflow.com/questions/3629835/why-is-stdfunction-not-equality-comparable – MW_dev Sep 17 '14 at 04:04
-
`std::function` doesn't have to refer to a function pointer. What does it mean for two functions to be equal anyway? It's a dubious operation to begin with, even before you get to `std::function`. – n. m. could be an AI Aug 18 '20 at 06:48
6 Answers
operator== for std::function compares a std::function with a null pointer, as far as I can tell the standard does not provide any details as to why.
Although, this boost FAQ entry, Why can't I compare boost::function objects with operator== or operator!=? provides a rationale and as far as I can tell should be applicable to std::function as well. Quoting the FAQ:
Comparison between boost::function objects cannot be implemented "well", and therefore will not be implemented. [...]
it then outlines requested solutions similar to Preet's and goes on to say:
The problem occurs when the type of the function objects stored by both f and g doesn't have an operator==[...]
and explains why this has to has to be dealt with in either the assignment operator or constructor and then goes on to say:
All of these problems translate into failures in the boost::function constructors or assignment operator, even if the user never invokes operator==. We can't do that to users.
Update
Found a standards rationale in Accessing the target of a tr1::function object, which is pretty old but is consistent with the boost FAQ and says:
operator== is unimplementable for tr1::function within the C++ language, because we do not have a reliable way to detect if a given type T is Equality Comparable without user assistance.

- 154,301
- 39
- 440
- 740
You can actually get it to work with .target
:
template<typename T, typename... U>
size_t getAddress(std::function<T(U...)> f) {
typedef T(fnType)(U...);
fnType ** fnPointer = f.template target<fnType*>();
return (size_t) *fnPointer;
}
if (getAddress(f) == getAddress(g)) {...}
(Ref: C++ trying to get function address from a std::function)
-
Magic, thanks. For some reason my attempts at this without templating returned different function pointers for two std::function wrappers of the same function. Curious! – andybuckley Apr 19 '16 at 09:37
-
2Converting function pointer to `size_t` is conditionally-supported with implementation-defined semantics. So this solution may not be portable. – M.M Dec 13 '17 at 03:45
-
5This only works if the wrapped object is a function pointer, not if it is a callable class or one of several other things that can be wrapped by a `std::function` – Baruch Jan 14 '18 at 10:04
-
If you know the type of the target, then perhaps you don't need `std::function` to begin with. – n. m. could be an AI Aug 18 '20 at 06:48
You could try comparing a
and b
first by comparing their .target_type()
and if these target type ids are the same, then you can compare their .target()
pointers. You can use a mismatching target type as an early out false.

- 8,417
- 28
- 36
-
5`target
()` requires knowing the type stored, not just knowing that it is the same. – Yakk - Adam Nevraumont Dec 30 '13 at 05:09 -
You mean the type of function? Because I think I can actually do that. – JesseTG Dec 30 '13 at 22:15
Be aware that equality of functions (deciding if two functions have always the same observable behavior) is an undecidable problem in lambda calculus (and that is why many programming languages forbid comparing functions; or at least closures; two very different functions can have the same observable behavior: for example, rename the variables in the C code of one function by another one, or do manually some loop unrolling, etc...).
So even if the ==
test compiles, it would at most just test that the code is identical (has the same address), not that the compared functions have the same behaviour.

- 223,805
- 18
- 296
- 547
-
1You can perfectly compare two bare function pointers against each other and get the expected result... I don't think it has much to do with lambda caculus. – Alexis Wilke Sep 26 '21 at 19:39
-
But what about comparing two closures (or lambda expressions, or anonymous functions)? – Basile Starynkevitch Sep 27 '21 at 03:53
What about comparing two shared_ptr?
using MessageFilter = std::function<void(const int msgID)>;
static void onMessageReceived(const int msgID)
{
std::cout << "msg id => " << msgID << std::endl;
}
static void someFunc()
{
auto filter = std::make_shared<MessageFilter>(&onMessageReceived);
if (filter && *filter)
{
(*filter)(1234);
}
}
As you can see, 'filter' is a shared_ptr, so it is easy to compare with another.

- 601
- 5
- 12
-
Thank you, we used your suggestion in our [Delegates template library](https://github.com/linksplatform/Delegates/blob/d7e6ee5808daeed70b5f47cc342cfd651de30dd0/cpp/Platform.Delegates/Platform.Delegates.Delegate.h#L92). This way we were able to remove hack code where we were trying to compare std::function byte by byte. Your solution is much simpler and works immediately on all platforms. – Konard Oct 21 '21 at 17:27
-
Then you compare shared_ptrs and not their contents, which are function pointers. So again we are in the same! – Mert Mertce Jun 15 '22 at 21:14
-
@MertMertce sometimes the only thing that is needed is to compare to know if it is the same object or not. When pointer is equal the underlying data is the same, and that may be the most reliable way to test if we deal with the same function. std::function itself does not implement equality check, and we not found any other reliable way to compare all possible values of std::function. So compare by pointer is good enough, if anyway you cannot compare underlying data reliably. – Konard Nov 25 '22 at 14:18
-
For example pointers are good enough to keep track of functions added to a list. If you add function by pointer you can be sure you can now delete the same function from the list later using this pointer. This may be used to implement simple multicast delegate (when one delegate is called it calls a list of functions inside) based events. – Konard Nov 25 '22 at 14:26