Range-based for loop and ADL

Discussion in 'C++' started by Johannes Schaub (litb), Sep 5, 2010.

  1. Range-based for loop description says 6.5.4/1:

    "... begin-expr and end-expr are begin(__range) and end(__range),
    respectively, where begin and end are looked up with argument-dependent
    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 block-scope function declaration that is not a using-declaration, 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?!

    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)
    ;
    }
     
    Johannes Schaub (litb), Sep 5, 2010
    #1
    1. Advertising

  2. * Johannes Schaub (litb), on 05.09.2010 21:34:
    > Range-based for loop description says 6.5.4/1:
    >
    > "... begin-expr and end-expr are begin(__range) and end(__range),
    > respectively, where begin and end are looked up with argument-dependent
    > 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 block-scope function declaration that is not a using-declaration, 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>
     
    Alf P. Steinbach /Usenet, Sep 5, 2010
    #2
    1. Advertising

  3. Alf P. Steinbach /Usenet wrote:

    > * Johannes Schaub (litb), on 05.09.2010 21:34:
    >> Range-based for loop description says 6.5.4/1:
    >>
    >> "... begin-expr and end-expr are begin(__range) and end(__range),
    >> respectively, where begin and end are looked up with argument-dependent
    >> 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 block-scope function declaration that is not a using-declaration, 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).
    >


    That's the interpretation I would like the spec to intend. But it says
    "looked up with argument-dependent lookup", and "let Y be the lookup set
    produced by argument dependent lookup (defined as follows). ... Y is the set
    of declarations found in the namespaces associated with the argument types
    as described below."

    This seems to say that only Y is taken for the set of declarations for
    begin/end. The sentence "The set of declarations found by the lookup of the
    name is the union of X and Y" surely sounds weird to me. Why does it define
    what the lookup set of argument dependent lookup *is* and then define it a
    second time? What i suspect is that this second sentence is meant to define
    the lookup set where ADL is entered by unqualified lookup (i.e by 3.4.1/3 -
    that paragraph defines the entire lookup-set by the ADL paragraphs!).

    But nonetheless, I really find this absolutely confusing. I tested GCC's
    current implementation of this (there is a patch available), and it ignores
    local declarations, seemingly ignoring X.
     
    Johannes Schaub (litb), Sep 5, 2010
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Question about ADL

    , Apr 29, 2004, in forum: C++
    Replies:
    5
    Views:
    358
    Dave Moore
    Apr 29, 2004
  2. Fraser Ross

    using declaration and ADL

    Fraser Ross, Sep 9, 2005, in forum: C++
    Replies:
    5
    Views:
    262
    Victor Bazarov
    Sep 9, 2005
  3. Chris Johnson
    Replies:
    6
    Views:
    349
    Chris Johnson
    Jul 3, 2006
  4. cgv
    Replies:
    2
    Views:
    377
    =?ISO-8859-15?Q?Jens_M=FCller?=
    Oct 14, 2006
  5. Isaac Won
    Replies:
    9
    Views:
    419
    Ulrich Eckhardt
    Mar 4, 2013
Loading...

Share This Page