From: Douglas Gregor (gregod_at_[hidden])
Date: 2004-03-11 17:52:12
On Thursday 11 March 2004 04:49 pm, Peter Dimov wrote:
> For some reason, I think that you are busy and don't have much time to read
> your e-mail. :-)
Ha ha! You are so very, very right :) But the fact that I have just a little
time to read my e-mail is the real danger. Kind of like having just a little
knowledge of explosives...
> The problem here is that you are establishing an idiom that represents
> 'contains' via the following signatures:
> template<...> bool operator==(function<...> const & f, G g);
> template<...> bool operator==(G g, function<...> const & f);
> My point is that this idiom is not applicable to other function<>-like
> classes, because if you also have
> template<...> bool operator==(my_function<...> const & f, G g);
> template<...> bool operator==(G g, my_function<...> const & f);
> you can neither ask a function<> whether it contains a my_function<>, nor
> can you ask a my_function<> whether it contains a function<>, as both
> classes claim the mixed operator== for _their_ 'contains' operation.
I understand. This will result in a compilation error, because the operator==
invocation would be ambiguous.
> > I'd bet that this results in a compilation error, so the user would
> > know to try on of these syntaxes:
> >> g.contains(h); // false
> >> h.contains(g); // true
> Good luck, if the authors haven't provided 'contains' as a member.
But any quality my_function<> will supply something like this, right?
> >> It's limited to the one and only function<> (and you can't even ask a
> >> function<> whether it contains another function<>, right?)
> > Right, you can't compare function<> objects, but you can compare a
> > function<> object to something it could target.
> A function<> can target another function<>, can it not?
So long as the types between the <>'s for the two are different, yes. But as
you know, you don't want to be using operator== to compare such things,
because it isn't clear which way to perform the containment check, and most
likely you really wanted to determine if the targets of the two function<>
objects are equal (but you're out of luck).
I actually did consider these issues before committing operator== for
function<> objects. We have:
function<FT> == function<FT>: still a compilation error, because we can't
function<FT1> == function<FT2>: a compilation error, because it isn't clear
which way to check for containment and you probably don't want to do it
function<FT> == my_function<...>: a compilation error if my_function<...>
has the same type of operator== that function does. Same rationale as the
case above with different function<...> operations.
function<FT> == F or F == function<FT>: checks containment
The "contains" member is there precisely because I knew about the cases where
we want to check containment but don't want to use operator==. I guess the
above will either convince you that:
1) operator== is sufficiently limited so that it is safe to use, because bad
uses end up with compiler errors.
2) operator== is still a terrible way to represent check the containment
relationship, and turns into a bloody mess of requirements.
I'm still on the side of #1, but do note that I have a monomaniacal obsession
with making function<> able to completely, totally, and utterly replace
function pointers and member function pointers with a minimum of effort.
Low-level abstractions MUST DIE!
Doug, slightly off the rocker
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk