Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2004-01-21 10:27:07


Douglas Paul Gregor wrote:
> On Wed, 21 Jan 2004, Peter Dimov wrote:
>> Douglas Paul Gregor wrote:
>>> boost::bind would need to be EqualityComparable for this to work,
>>> and
>>> at the moment it is not. It's technically trivially to do, we need
>>> only convince Peter :)
>>
>> There are some interesting corner cases.
>>
>> int a = 1, b = 1;
>>
>> int f(int x) { return x; }
>>
>> bind(f, a) == bind<int>(f, a); // true, false, or ill-formed?
>
> True, I think.

The underlying question here is that whether bind() should support
heterogeneous comparisons at all, since the types of the two bind()
expressions are not required to match. It's either true or ill-formed, but
which one? Ill-formed is the technically trivial thing to do, the other is a
bit more complicated. Is the complexity needed?

> We could make a case for ignoring the return type
> entirely, because bind expressions with equal arguments should produce
> function objects that always have the same result type...

That's dangerous.

struct F
{
    typedef void result_type;
    void operator()(int) const;
    void operator()(long) const;
};

bool operator==(F, F) { return true; }

bind(F(), bind<int>(f, 0)) == bind(F(), bind<long>(f, 0)); // true?

>> bind(f, 1) == bind(f, 1L); // true, false, or ill-formed?
>
> True. It seems that the types don't matter at all so long as they are
> comparable via ==. One could even have a boost::function<> object on
> one side and a bind expression equivalent to the one stored in the
> boost::function<> object on the other side, and they would compare
> equal.

Same as above:

    bind(F(), 1) == bind(F(), 1L); // true?

>> bind(f, ref(a)) == bind(f, ref(b)); // true or false?
>
> Now _that_ is an interesting corner case.
>
> If we say it's "true", I think we're being true to the notion that
> reference_wrapper really is like a reference. But, of course, it's obvious
> to us that those two function objects won't always give the same
> results.

Indeed, and note that "true" implies that it would be ill-formed when a and
b cannot be compared, which is rather common for ref()-passed objects
(identity semantics, noncopyable).

[...]

> Users using ref() when they should be passing a pointer beware. There
> be dragons that way.

But you can't choose one or the other at will. You are limited by the
signature of the function object that you adapt.

>> and the related question whether reference_wrapper needs operator==
>> and if so, what are its semantics. However, ...
>
> Whatever we do, I do not want reference_wrapper to have its own
> operator==.

Sounds reasonable, although such an operator== doing a pointer comparison is
the technically trivial thing to do here.


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