Boost logo

Boost Users :

Subject: Re: [Boost-users] Equality comparison of boost::function<>
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2009-08-10 11:51:32


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<void (int, int, int)> f = bind(foo, _1, _2, _3);
> boost::function<void (int, int, int)> 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


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net