* Johannes Schaub (litb), on 05.09.2010 21:34:
> Rangebased for loop description says 6.5.4/1:
>
> "... beginexpr and endexpr are begin(__range) and end(__range),
> respectively, where begin and end are looked up with argumentdependent
> lookup (3.4.2)."
>
> And 3.4.2 says at 3.4.2/3:
>
> "Let X be the lookup set produced by unqualiﬁed lookup (3.4.1) and let Y be
> the lookup set produced by argument dependent lookup (deﬁned as follows). If
> X contains
>
>  a declaration of a class member, or
>  a blockscope function declaration that is not a usingdeclaration, or
>  a declaration that is neither a function or a function template
>
> then Y is empty. Otherwise Y is the set of declarations found in the
> namespaces associated with the argument types as described below. The set of
> declarations found by the lookup of the name is the union of X and Y"
>
>
> WTF!? Now is the following code valid? I.e is the set of declarations found
> the union of X and Y or is it only Y?!
It's always the union of X and Y; the only question is whether Y is empty (ADL
lookup not performed).
> struct Foo {
> typedef int *iterator;
> int *begin() { return array; }
> int *end() { return array + 2; }
>
> int array[2];
> };
>
> namespace ranges {
> template<typename T>
> typename T::iterator begin(T&t) { return t.begin(); }
>
> template<typename T>
> typename T::iterator end(T&t) { return t.end(); }
> }
>
> int main() {
> // Is "X" included in the set of declarations found!?
> using ranges::begin;
> using ranges::end;
>
> Foo f = { 1, 2 };
> for(int a : f)
> ;
Here unqualified lookup producing set X finds the 'begin' and 'end' introduced
by the 'using' declarations, so they're in the set X, but this is not
sufficient to prohibit ADL. And so ADL is performed. However, ADL finds nothing
(I think), and so Y is empty.
The union of X and Y is then identical to X.
And in set X you have the 'begin' and 'end' introduced by the 'using' declarations.
> }
Cheers & hth.,
 Alf

blog at <url: http://alfps.wordpress.com>
