From 2c708069e8c2e3953f3945b98345537ef54af87e Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Sun, 12 Oct 2003 16:02:26 +0000 Subject: [PATCH] Answer the eternal operator== question. [SVN r20356] --- doc/faq.xml | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/doc/faq.xml b/doc/faq.xml index c9e9ac6..395442c 100644 --- a/doc/faq.xml +++ b/doc/faq.xml @@ -5,6 +5,87 @@ Frequently Asked Questions + + Why can't I compare + boost::function objects with + operator== or + operator!=? + + + 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: + + + Fails at compile-time for objects where + operator== is not accessible (e.g., because it is + private). + + Fails at compile-time if calling + operator== is ambiguous. + + 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. + + + I see void pointers; is this [mess] type safe?