Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2005-09-18 17:37:37


Thorsten Ottosen <nesotto_at_[hidden]> writes:

> David Abrahams <dave <at> boost-consulting.com> writes:
>
>>
>> Thorsten Ottosen <nesotto <at> cs.aau.dk> writes:
>
>> >> How about
>> >>
>> >> range_begin(x) if it would invoke a function found by argument
>> >> dependent lookup.
>> >>
>> >> ?
>> >
>
>> > but it also appears fairly cryptic to me.
>>
>> What's cryptic about it?
>
> the compiler doesn't care about invoking something...that happens at
> runtime IMO.

Of course it does. The _determination_ of whether an expression would
invoke something found by ADL is one of the compiler's jobs.

>> Here are a few other options that are
>> similarly precise:
>>
>> range_begin(x) if it would result in range_begin being found by
>> argument dependent lookup.
>>
>> range_begin(x) if there is a matching range_begin in a namespace
>> associated with the type of x.
>>
>> > If the only problem was
>> > that ADL applies to function overloads (or names in general), then
>> > why not just strip the "(x)":
>> >
>> > range_begin(x) if range_begin can be found by ADL
>> >
>> > ? Wouldn't this account for all names (not just function overloads)?
>>
>> It lacks precision; it doesn't force that range_begin that's found to
>> be in a namespace associated with the single argument x.
>
> hm...AFAICT, only the last of your three versions mentions the namespace
> associated with x.

Namespaces, plural.

The others mention them by implication; if you carefully think through
each one you'll see that.

>> Just because there's a range_begin that *can* be found via ADL
>> doesn't mean it will be found in that expression.
>
> ok, I think I'm getting it...for example, the a base class version
> of begin can be found, but derived to base classs reference will not happen
> and so t.begin() is called instead.

No, in fact the namespace of a base class is an associated namespace
of the derived class, so it works. I mean, for example, that there
might be range_begin that applies to some unrelated type Y (with
instance y) such that range_begin(y) finds a range_begin overload via
ADL. As you see, range_begin *can* be found via ADL... when called
with an argument of type y.

> I like this version best:
>
> range_begin(x) if it would result in range_begin being found by
> ADL

Fine with me.

>> This is nitpicky, but I think the
>> language is slightly clearer.
>
> right. somehow we still don't say when it wouldn't be found.

I don't follow.

> The question is, maybe, is the overload actually found, but then
> later, during overload resolution, discarded as a best match?

I think you are saying quite clearly that it will not be
discarded... but after a little investigation I can see that it could, so...

> In that light I think
>
> range_begin(x) if there is an exactly matching range_begin in a
> namespace associated with x.
>
> is better.
> we then need to state that "exactly matching" means without no
> implicit conversions required.

I think you are right... almost.

0. The standard uses the term "an exact match," which is already
   clear that there are no conversions.

1. The namespace is associated with the _type_ of x, not with x
   itself.

2. isn't template <class T> int range_begin(T) in an associated
   namespace an exact match? Because, if so, that will cause an
   ambiguity with the one in the range library

Maybe the thing to do is just expose all the details: show the
semantics of begin(x) as return range_begin(x), and document the
range_begin overloads that are in the library.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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