Boost logo

Boost :

From: Douglas Gregor (gregod_at_[hidden])
Date: 2003-10-12 11:02:28


On Sunday 12 October 2003 05:30 am, Firingme wrote:
> I've read Herb Sutter's CUJ article
> <<Generalizing Observer>> from
>
> http://www.cuj.com/documents/s=8840/cujexp0309sutter/
>
> And in that article Herb suggest add
>
> 1: Equality Comparison

I just added this entry to the Function FAQ to answer your question:

Comparison between boost::function objects cannot be implemented "well", and
therefore will not be implemented. The typical semantics requested for f == g
given boost::function objects f and g are:

    * If f and g store function objects of the same type, use that type's
operator== to compare them.
    * If f and g store function objects of different types, return false.

The problem occurs when the type of the function objects stored by both f and
g doesn't have an operator==: we would like the expression f == g to fail to
compile, as occurs with, e.g., the standard containers. However, this is not
implementable for boost::function because it necessarily "erases" some type
information after it has been assigned a function object, so it cannot try to
call operator== later: it must either find a way to call operator== now, or
it will never be able to call it later. Note, for instance, what happens if
you try to put a float value into a boost::function object: you will get an
error at the assignment operator or constructor, not in operator(), because
the function-call expression must be bound in the constructor or assignment
operator.

The most promising approach is to find a method of determining if operator==
can be called for a particular type, and then supporting it only when it is
available; in other situations, an exception would be thrown. However, to
date there is no known way to detect if an arbitrary operator expression f ==
g is suitably defined. The best solution known has the following undesirable
qualities:

   1. Fails at compile-time for objects where operator== is not accessible
(e.g., because it is private).
   2. Fails at compile-time if calling operator== is ambiguous.
   3. Appears to be correct if the operator== declaration is correct, even
though operator== may not compile.

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.

The other option is to place the burden on users that want to use operator==,
e.g., by providing an is_equality_comparable trait they may specialize. This
is a workable solution, but is dangerous in practice, because forgetting to
specialize the trait will result in unexpected exceptions being thrown from
boost::function's operator==. This essentially negates the usefulness of
operator== in the context in which it is most desired: multitarget callbacks.
The Signals library has a way around this.

> 2: Multicast Support

I agree with Edward's answer to this.

        Doug


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk