class member name lookup issues

Discussion in 'C++' started by ZMZ, Jan 20, 2011.

  1. ZMZ

    ZMZ Guest

    Hi all,

    I am very confused about the standard n3225 10.2/13,

    [ Note: Even if the result of name lookup is unambiguous, use of a
    name found in multiple subobjects might still be ambiguous (4.11,
    5.2.5, 5.3.1, 11.2).—end note ] [ Example:

    struct B1 {
    void f();
    static void f(int);
    int i;
    };
    struct B2 {
    void f(double);
    };
    struct I1: B1 { };
    struct I2: B1 { };
    struct D: I1, I2, B2 {
    using B1::f;
    using B2::f;
    void g() {
    f(); // Ambiguous conversion of this
    f(0); // Unambiguous (static)
    f(0.0); // Unambiguous (only one B2)
    int B1::* mpB1 = &D::i; // Unambiguous
    int D::* mpD = &D::i; // Ambiguous conversion
    }
    };
    I cannot see why this is unambiguous int B1::* mpB1 = &D::i; //
    Unambiguous

    Visual C++, Gcc and CLang all say that it is ambiguous access to D::i!

    The wording seems to be related to the core issue #39
    http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#39, and
    the final proposal is here: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1626.pdf

    I now find that the new algorithm-based wordings (10.2/3-10.2/6) are
    even more confusing because none of the note in 10.2/9, 10.2/10,
    10.2/11, and 10.2/13 fully complies with 10.2/3-10.2/6. I can take
    10.2/9-10.2/11 as exceptions, but I am especially confused about
    10.2/13. I have no idea on the intention of 10.2/13.

    How should the example in 10.2/13 be looked-up according to the
    10.2/3-10.2/6? What's the intention of 10.2/13, i.e., what's the
    situation of which 10.2/13 is considered as an exception of
    10.2/3-10.2/6?

    Please give me some hints. Thank you very much.
    ZMZ, Jan 20, 2011
    #1
    1. Advertising

  2. ZMZ wrote:

    > Hi all,
    >
    > I am very confused about the standard n3225 10.2/13,
    >
    > [ Note: Even if the result of name lookup is unambiguous, use of a
    > name found in multiple subobjects might still be ambiguous (4.11,
    > 5.2.5, 5.3.1, 11.2).—end note ] [ Example:
    >
    > struct B1 {
    > void f();
    > static void f(int);
    > int i;
    > };
    > struct B2 {
    > void f(double);
    > };
    > struct I1: B1 { };
    > struct I2: B1 { };
    > struct D: I1, I2, B2 {
    > using B1::f;
    > using B2::f;
    > void g() {
    > f(); // Ambiguous conversion of this
    > f(0); // Unambiguous (static)
    > f(0.0); // Unambiguous (only one B2)
    > int B1::* mpB1 = &D::i; // Unambiguous
    > int D::* mpD = &D::i; // Ambiguous conversion
    > }
    > };
    > I cannot see why this is unambiguous int B1::* mpB1 = &D::i; //
    > Unambiguous
    >


    &D::i has type "int B1::*", and unambiguously refers to data member "i" of
    B1. If you dereference it with a D object or if you assign it to a "int
    D::*", you will get an ambiguity as needed.

    > Visual C++, Gcc and CLang all say that it is ambiguous access to D::i!
    >


    None of those compilers implement 10.2 yet.


    > The wording seems to be related to the core issue #39
    > http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#39, and
    > the final proposal is here:
    > http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1626.pdf
    >
    > I now find that the new algorithm-based wordings (10.2/3-10.2/6) are
    > even more confusing because none of the note in 10.2/9, 10.2/10,
    > 10.2/11, and 10.2/13 fully complies with 10.2/3-10.2/6. I can take
    > 10.2/9-10.2/11 as exceptions, but I am especially confused about
    > 10.2/13. I have no idea on the intention of 10.2/13.
    >


    You need to give examples that show what you don't understand.

    > How should the example in 10.2/13 be looked-up according to the
    > 10.2/3-10.2/6? What's the intention of 10.2/13, i.e., what's the
    > situation of which 10.2/13 is considered as an exception of
    > 10.2/3-10.2/6?
    >


    The new algorithm based lookup rules decouples runtime concerns (finding an
    unique object) from compile time/lookup concerns (finding a declaration that
    a name refers to).

    The following is well-formed with the new wording:

    struct Z { int z; };
    struct X : Z { };
    struct Y : Z { };
    struct A : X, Y { };

    struct B : A {
    using A::z;
    };

    The declaration "using A::x;" introduces a member name into A that refers to
    the declaration "Z::z". In a declarative context, this is perfectly fine. An
    error is risen only when you access "B::z" as a member access expression
    (5.2.5).

    There is currently a confusion about using declarations in general though,
    in my opinion. A using declaration introduces a new member name into a
    scope. Name lookup looks through the using declaration, but some paragraphs
    in the spec assumes it doesn't (overload resolution in particular). A second
    problem, in my opinion, is that 10.2p3 says "type declarations are replaced
    by the types they designate". That doesn't make sense: "typedef int type;"
    what will a lookup for "type" yield?
    Johannes Schaub (litb), Jan 20, 2011
    #2
    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. E11
    Replies:
    1
    Views:
    4,700
    Thomas Weidenfeller
    Oct 12, 2005
  2. Siemel Naran
    Replies:
    4
    Views:
    783
    Micah Cowan
    Jan 12, 2005
  3. Fraser Ross

    member name lookup

    Fraser Ross, Dec 20, 2007, in forum: C++
    Replies:
    3
    Views:
    344
    Victor Bazarov
    Dec 20, 2007
  4. Ravi
    Replies:
    1
    Views:
    564
    Chris Rebert
    Feb 27, 2009
  5. Replies:
    3
    Views:
    403
    Ivan Sorokin
    Sep 18, 2012
Loading...

Share This Page