MI and ambiguous members

Discussion in 'C++' started by Chameleon, Jan 4, 2007.

  1. Chameleon

    Chameleon Guest

    Can anyone explain me why the code below produce (with mingw-g++) the
    following error message:
    ---------------------------------------------------------------
    main10.cpp: In function `int main()':
    main10.cpp:23: error: request for member `getZero' is ambiguous
    main10.cpp:12: error: candidates are: virtual int B::getZero(int)
    main10.cpp:6: error: virtual int A::getZero()
    ---------------------------------------------------------------

    No! member getZero is not ambiguous at all because
    int A::getZero()
    is completelly different from
    int B::getZero(int a)

    Compiler can exactly decide what member to call when I say
    c.getZero()
    it is A::getZero() because B::getZero(int) has parameters.

    Is this a compiler (gcc) or a language limitation?

    Thanks!

    -----------------------------------------------------
    #include <cstdio>

    class A
    {
    public:
    virtual int getZero() { return 0; }
    };

    class B
    {
    public:
    virtual int getZero(int a) { return a - a; }
    };

    class C : public A, public B {};


    int main()
    {
    C c;
    printf("%d", c.getZero());
    return 0;
    }
    ------------------------------------------------------
     
    Chameleon, Jan 4, 2007
    #1
    1. Advertising

  2. Chameleon

    Chameleon Guest

    Re: ambiguous members

    Simpler paradigm with no Multiple Inheritance

    > Can anyone explain me why the code below produce (with mingw-g++) the
    > following error message:
    > ---------------------------------------------------------------

    main10a.cpp: In function `int main()':
    main10a.cpp:19: error: no matching function for call to `C::getZero()'
    main10a.cpp:12: note: candidates are: virtual int C::getZero(int)
    > ---------------------------------------------------------------
    >
    > No! member getZero is not ambiguous at all because
    > int A::getZero()
    > is completelly different from
    > int C::getZero(int a)
    >
    > Compiler can exactly decide what member to call when I say
    > c.getZero()
    > it is A::getZero() because C::getZero(int) has parameters.
    >
    > Is this a compiler (gcc) or a language limitation?
    >
    > Thanks!
    >
    > -----------------------------------------------------

    #include <cstdio>

    class A
    {
    public:
    virtual int getZero() { return 0; }
    };

    class C : public A
    {
    public:
    virtual int getZero(int a) { return a-a; }
    };

    int main()
    {
    C c;
    printf("%d", c.getZero());
    return 0;
    }
    > ------------------------------------------------------
     
    Chameleon, Jan 4, 2007
    #2
    1. Advertising

  3. Chameleon

    bjeremy Guest

    Re: ambiguous members

    Chameleon wrote:
    > Simpler paradigm with no Multiple Inheritance
    >
    > > Can anyone explain me why the code below produce (with mingw-g++) the
    > > following error message:
    > > ---------------------------------------------------------------

    > main10a.cpp: In function `int main()':
    > main10a.cpp:19: error: no matching function for call to `C::getZero()'
    > main10a.cpp:12: note: candidates are: virtual int C::getZero(int)
    > > ---------------------------------------------------------------
    > >
    > > No! member getZero is not ambiguous at all because
    > > int A::getZero()
    > > is completelly different from
    > > int C::getZero(int a)
    > >
    > > Compiler can exactly decide what member to call when I say
    > > c.getZero()
    > > it is A::getZero() because C::getZero(int) has parameters.
    > >
    > > Is this a compiler (gcc) or a language limitation?
    > >
    > > Thanks!
    > >
    > > -----------------------------------------------------

    > #include <cstdio>
    >
    > class A
    > {
    > public:
    > virtual int getZero() { return 0; }
    > };
    >
    > class C : public A
    > {
    > public:
    > virtual int getZero(int a) { return a-a; }
    > };
    >
    > int main()
    > {
    > C c;
    > printf("%d", c.getZero());
    > return 0;
    > }
    > > ------------------------------------------------------


    You're trying to use polymorphism with with the object, not a pointer
    or reference to the object. Also, A::getZero() is not overridden in C,
    so simply changing your definition to new a C pointer or reference
    will not help you out. Your Declaration of "C c" simply has no way of
    knowing A::getZero(), so it thinks you really mean C::getZero(int).

    I'm not sure of your actual semantics or what you wish to do.. but two
    ways to get around your error
    1. Try changing your definition "C c" to "A *c = new C;" (and use ->
    instead of . or=f course)
    2. Keep your current declaration, and override A::getZero() in C

    also... you may want to use std::cout instead of printf... but thats
    not relevent to your original question.
     
    bjeremy, Jan 4, 2007
    #3
  4. Chameleon

    Yan Guest

    Re: ambiguous members

    Chameleon wrote:
    > Simpler paradigm with no Multiple Inheritance
    >
    > > Can anyone explain me why the code below produce (with mingw-g++) the
    > > following error message:
    > > ---------------------------------------------------------------

    > main10a.cpp: In function `int main()':
    > main10a.cpp:19: error: no matching function for call to `C::getZero()'
    > main10a.cpp:12: note: candidates are: virtual int C::getZero(int)
    > > ---------------------------------------------------------------
    > >
    > > No! member getZero is not ambiguous at all because
    > > int A::getZero()
    > > is completelly different from
    > > int C::getZero(int a)
    > >
    > > Compiler can exactly decide what member to call when I say
    > > c.getZero()
    > > it is A::getZero() because C::getZero(int) has parameters.
    > >
    > > Is this a compiler (gcc) or a language limitation?
    > >
    > > Thanks!
    > >
    > > -----------------------------------------------------

    > #include <cstdio>
    >
    > class A
    > {
    > public:
    > virtual int getZero() { return 0; }
    > };
    >
    > class C : public A
    > {
    > public:
    > virtual int getZero(int a) { return a-a; }
    > };
    >
    > int main()
    > {
    > C c;
    > printf("%d", c.getZero());
    > return 0;
    > }
    > > ------------------------------------------------------


    Name hiding rules in C++ is the reason for that. Function(s) in derived
    class hide function(s) with the same name in the base class, whether
    virtual or not. In your case C::getZero hides A::getZero. Doesn't
    matter that they have different signatures - they don't get overloaded
    as someone might expect.
     
    Yan, Jan 4, 2007
    #4
  5. Chameleon

    John Carson Guest

    Re: ambiguous members

    "Chameleon" <> wrote in message
    news:enjbla$pph$
    > Simpler paradigm with no Multiple Inheritance
    >
    >> Can anyone explain me why the code below produce (with mingw-g++) the
    >> following error message:
    >> ---------------------------------------------------------------

    > main10a.cpp: In function `int main()':
    > main10a.cpp:19: error: no matching function for call to `C::getZero()'
    > main10a.cpp:12: note: candidates are: virtual int C::getZero(int)
    >> ---------------------------------------------------------------
    >>
    >> No! member getZero is not ambiguous at all because
    >> int A::getZero()
    >> is completelly different from
    >> int C::getZero(int a)
    >>
    >> Compiler can exactly decide what member to call when I say
    >> c.getZero()
    >> it is A::getZero() because C::getZero(int) has parameters.
    >>
    >> Is this a compiler (gcc) or a language limitation?
    >>
    >> Thanks!
    >>
    >> -----------------------------------------------------

    > #include <cstdio>
    >
    > class A
    > {
    > public:
    > virtual int getZero() { return 0; }
    > };
    >
    > class C : public A
    > {
    > public:
    > virtual int getZero(int a) { return a-a; }
    > };
    >
    > int main()
    > {
    > C c;
    > printf("%d", c.getZero());
    > return 0;
    > }
    >> ------------------------------------------------------


    As Yan points out regarding the second example, getZero in C hides getZero
    in A. They are not treated as overloads.

    You can get them treated as overloads, however, by adding

    using A::getZero;

    to the declaration of C.

    As for your first multiple inheritance example, once again, overloads are
    not made across classes. As Stroustrup points out: "When combining
    essentially unrelated classes...similarity in naming typically does not
    indicate a common purpose."

    Because overloading is not done across classes, C++ just looks at the names
    and hence reports ambiguity.

    You can resolve the problem in the same way by bringing both functions into
    a common scope. Change class C to:

    class C : public A, public B
    {
    public:
    using A::getZero;
    using B::getZero;
    };


    --
    John Carson
     
    John Carson, Jan 5, 2007
    #5
    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. JFCM
    Replies:
    4
    Views:
    5,753
  2. CoolPint
    Replies:
    8
    Views:
    1,000
    Jeff Schwab
    Dec 14, 2003
  3. Dave
    Replies:
    3
    Views:
    371
    tom_usenet
    Aug 10, 2004
  4. hdixon
    Replies:
    3
    Views:
    653
    hdixon
    Jul 9, 2006
  5. lovecreatesbeauty
    Replies:
    43
    Views:
    1,307
    Keith Thompson
    Feb 6, 2006
Loading...

Share This Page