1

This is a continuation of my prior question. Note that the code below makes a virtual call at p->f(1.0) printing Derived::f(double).

#include <iostream>
#include <complex>
using namespace::std;

class Base
{
public:
    virtual void f(double);
    virtual ~Base() {};
};

void Base::f(double) { cout << "Base::f(double)\n"; }

class Derived : public Base {
public:
    void f(std::complex<double>);
    void f(double);
};

void Derived::f(std::complex<double>) { cout << "Derived::f(complex)\n"; }
void Derived::f(double) { cout << "Derived::f(double)\n"; }

int main()
{
    Derived* p = new Derived;
    p->f(1.0);
    delete p;
}

If I just eliminate the member function void f(double); in Derived, the code makes a static call to Derived::f(std::complex<double>).

What was it that made the compiler change from a dynamic call in the first example to a static call in the second? I would appreciate some quote from the Standard.

Edit:

The answers to the question to which this was considered a dup don't cite the Standard, as I asked above. Thanks.

Community
  • 1
  • 1
Wake up Brazil
  • 3,421
  • 12
  • 19
  • 2
    Did you expect something else to happen? – Mooing Duck May 19 '14 at 20:05
  • 1
    Why does everyone always write `new` and `delete` for those examples?! No need... – Kerrek SB May 19 '14 at 20:06
  • 1
    @KerrekSB maybe this explains: http://stackoverflow.com/a/334752/5987 – Mark Ransom May 19 '14 at 20:11
  • My answer to your original question answers this one too. :) Edit: But not with a quote from the standard. – dlf May 19 '14 at 20:37
  • 1
    Asking for a reference to the standard does *not* make your question different. If you really want that reference add a bounty to the other questions stating it as the reason for the bounty, or just comment an answer and ask for it. – Bakuriu May 24 '14 at 20:29

1 Answers1

3

What was it that made the compiler change from a dynamic call in the first example to a static call in the second?

The lookup rules. Without the declaration of f(double) in derived (and lacking a using-declaration) the f(complex<double>) hides f(double) in the base. When the compiler does lookup for p->f(1.0) inside Derived, finds an overload and given a single option uses it. It never moves up to Base to check whether there are different overloads.

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
  • 1
    It's worth stressing that this has nothing to do with virtual polymorphism at all. It's a simple property of class inheritance. – Kerrek SB May 19 '14 at 20:08
  • My understanding was that a virtual function declaration in the Base would always have priority in cases like this. Could you provide a specific quote from the Standard supporting what you said above? The other answer from which this was considered a dup doesn't cite the Standard. – Wake up Brazil May 19 '14 at 20:31
  • How about 10.2 of the C++11 draft standard (emphasis mine): "2. The following steps define the result of name lookup for a member name f in a class scope C... 4. If C contains a declaration of the name f, the declaration set contains every declaration of f declared in C that satisfies the requirements of the language construct in which the lookup occurs... If the resulting declaration set is not empty, the subobject set contains C itself, *and calculation is complete.* 5. Otherwise [look in the base class]." – dlf May 19 '14 at 20:43