
AMDG Zachary Turner wrote:
This is probably just my ignorance on the issue of boost::function implementation details, but I don't see why function objects can't be equality comparable.
They can be, but they don't have to be. Please see http://www.boost.org/doc/html/function/faq.html#id1877737
Again I don't know much about the details of boost::function implementation, but somewhere down there it has to have a typed copy of f otherwise it wouldn't be able to invoke operator(), so why couldn't it just compare typeids of those two instances?
If you want to compare typeids you can do it explicitly, since boost::function allows access to the typeid of the contained function object.
For function objects that contain state, it seems like it could just use deep equality testing of members. It's true that functors like std::less<> don't provide equality operators, but honestly for two instances of boost::function<> that both contain function objects, I'd be satisfied if boost::function just had an equality operator like this:
template<class Sig> bool operator==(const boost::function<Sig>& func1, const boost::function<Sig>& func2) { return (typeid(func1.internal_func_obj) == typeid(func2.internal_func_obj)) && (memcmp(&func1.internal_func_obj, &func2.internal_func_obj, sizeof(func1.internal_func_obj)) == 0); }
with internal_func_obj replaced with whatever, since again I'm not familiar with the implementation details.
This is problematic because it doesn't match normal C++ semantics.
It seems like even lambda expressions should be equality comparable provided they are exactly the same function object. So that two lambda functions both specified as (_1 + _2)(x, y) for example would be the same, but (_2 + _1)(x, y) would be different (even though they're actually the same provided + is commutative). I'm assuming that the construction of a boost::function<> object is deterministic given a lambda expression, but I think that's a reasonable assumption.
Even given
void foo(int a, int b, int c) {}
boost::function
f = bind(foo, _1, _2, _3); boost::function f = foo; I'd be fine if equality returned false.
This ought to return false because the types are different.
So in short, what is the flaw in just testing the way two function objects are represented internally
It would be surprising, because nothing else works that way. In Christ, Steven Watanabe