Boost logo

Boost :

Subject: Re: [boost] [guidelines] why template errors suck
From: Sebastian Redl (sebastian.redl_at_[hidden])
Date: 2010-09-28 16:04:03


On Sep 28, 2010, at 12:18 PM, John Bytheway wrote:

> For concreteness, I imagine that a "straightforward" implementation of
> find_if in concept land looks something like this (like everyone else
> here I reserve the right to get the syntax wrong, in my case having
> never worked with concepts this way before):
>
> template<InputIterator I, typename F>
> I find_if(I start, I const finish, F const p)
> where Predicate<F, InputIterator<I>::value_type>
> {
> while (start != finish && !p(*start)) ++start;
> return start;
> }
>
> Thus, I imagine that the pseudo-signature technique allows this
> implementation.
>
> Furthermore, I would have written the Predicate concept like
>
> auto concept Predicate<typename F, typename A>
> {
> bool operator()(A);
> }

Small syntax correction: You need F as the first parameter of that operator ().

>
> So, my first question is: will the above find_if compile?

Yes.

> If so, does
> it imply that predicates must return bool, or merely that they must
> return something convertible to bool?

The latter. That's why they're called pseudo-signatures.

> If the latter, then I don't see
> any difference from the valid expression approach.

The difference is that, no matter what the actual predicate returns, it is treated as a bool.

> So, I guess it is
> the former? In that case I think I see what you're driving at. It
> prevents me from writing a perverse predicate such as:
>
> struct funny_bool {
> operator bool() { return true; }
> bool operator!() { return true; }
> };
>
> struct predicate {
> funny_bool operator()(int) { return funny_bool; }
> };
>
> although that would have been fine under the valid-expressions framework
> (and have potentially surprising behaviour).

No, if I remember correctly how concepts work, that's actually a perfectly valid thing to do. In find_if<InputIterator, predicate>, p(*start) is bound to the pseudo-signature operator(), which returns a bool. Therefore, the result of p(*start) is converted to a bool first, and only then is operator ! applied to it, so you get the normal not-operator.

But I might remember incorrectly.

Sebastian


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