Topic: Compiler selection of member function


Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/10/01
Raw View
John Keenan wrote:
>
> Exactly what are the rules for the compiler to select a member function and
> where are these rules specified? What is the proper vocabulary when
> referring to how the compiler selects a member function?
>
> For example, consider the following:
>
> ----- MyBase.h ------
>     class MyBase
>     {
>         virtual hello( CString& );
>         virtual hello( int );
>     }
> ----- MyDerived.h -----
>     #include "MyBase.h"
>     class MyDerived : public MyBase
>     {
>         virtual hello( int );
>     }
> ----- SomeUser.cpp -----
>     #include "MyDerived.h"
>     MyBase aMyBase;
>     aMyBase.hello( 3 ); // no problem
>     aMyBase.hello( "hello there" ); // no problem
>     MyDerived aMyDerived;
>     aMyDerived.hello( 3 ); // no problem
>     aMyDerived.hello( "hello there" ); // This line fails to compile because
>         // "hello there" can not be converted to an int.
>

I guess you just forgot some "public:" here - otherwise the
code would fail on each of the constructor calls.

> From the above example I have dedueced that once the compiler finds a member
> name in a derived class ('hello' in this case), it will stop searching
> further up the heirarchy and will instead insist that this derived class
> supply the member function with the correct arguments. In my questions above
> I am simply trying to find out more about this subject.

Your analysis is right. The situation is quite the same as
the following:

void foo(int) {}
void foo(char const*) {}

void bar()
{
  void foo(int); // redeclare foo(int) here
  foo("Hello");  // Error: no suitable version
                 // (::foo(char const*) is hidden)
}

and the rule is the same which makes the following work:

int i;

void bar()
{
  int i;
  i = 5; // There is no ambiguity here, since ::i is hidden
}

That is, once the name is found, enclosing scopes
(and base class scopes are "enclosing") are not searched.

However, there's a workaround: You can tell the compiler
explicitly that you want to import the name:

class MyDerived: public MyBase
{
  using MyBase::hello;     // "import" Base hello explicily
  virtual void Hello(int); // override this function
}

With this addition, everything should work.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "John Keenan" <jskeenan@primustech.com>
Date: 1999/10/01
Raw View
Exactly what are the rules for the compiler to select a member function and
where are these rules specified? What is the proper vocabulary when
referring to how the compiler selects a member function?

For example, consider the following:

----- MyBase.h ------
    class MyBase
    {
        virtual hello( CString& );
        virtual hello( int );
    }
----- MyDerived.h -----
    #include "MyBase.h"
    class MyDerived : public MyBase
    {
        virtual hello( int );
    }
----- SomeUser.cpp -----
    #include "MyDerived.h"
    MyBase aMyBase;
    aMyBase.hello( 3 ); // no problem
    aMyBase.hello( "hello there" ); // no problem
    MyDerived aMyDerived;
    aMyDerived.hello( 3 ); // no problem
    aMyDerived.hello( "hello there" ); // This line fails to compile because
        // "hello there" can not be converted to an int.



Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/10/02
Raw View
In article <q%2J3.5952$t%3.491682@typ11.nn.bcandid.com>, John Keenan
<jskeenan@primustech.com> writes
>From the above example I have dedueced that once the compiler finds a member
>name in a derived class ('hello' in this case), it will stop searching
>further up the heirarchy and will instead insist that this derived class
>supply the member function with the correct arguments. In my questions above
>I am simply trying to find out more about this subject.

C++ overloading requires that the search for candidates is limited to
the first of a set of nested scopes in which the name is found (e.g.
once it finds the name in Derived it will not search Base).  To
understand the complete rule you must study 'Koenig lookup' which
provides added scopes depending on the types of the explicit arguments.
However even the complete rule would not result in an outer scope being
searched once the name has been found in an inner scope.


Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: 1999/10/02
Raw View
John Keenan wrote:
>
> Exactly what are the rules for the compiler to select a member function and
> where are these rules specified? What is the proper vocabulary when
> referring to how the compiler selects a member function?

Section 10.2 of the C++ standard covers member name lookup.

> For example, consider the following:
>
> ----- MyBase.h ------
>     class MyBase
>     {
>         virtual hello( CString& );
>         virtual hello( int );
>     }
> ----- MyDerived.h -----
>     #include "MyBase.h"
>     class MyDerived : public MyBase
>     {
>         virtual hello( int );
>     }
> ----- SomeUser.cpp -----
>     #include "MyDerived.h"
>     MyBase aMyBase;
>     aMyBase.hello( 3 ); // no problem
>     aMyBase.hello( "hello there" ); // no problem
>     MyDerived aMyDerived;
>     aMyDerived.hello( 3 ); // no problem
>     aMyDerived.hello( "hello there" ); // This line fails to compile because
>         // "hello there" can not be converted to an int.
>
> From the above example I have dedueced that once the compiler finds a member
> name in a derived class ('hello' in this case), it will stop searching
> further up the heirarchy and will instead insist that this derived class
> supply the member function with the correct arguments. In my questions above
> I am simply trying to find out more about this subject.

The relevant rule here is that within the scope of MyDerived::hello(),
it hides all base class definitions of any function by that same name.

You also need a few "public:" statements in your class definitions.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]