11
struct B {
  void foo () {}
};

struct D : B {
  using B::foo;
  static void foo () {}
};

int main ()
{
  D obj;
  obj.foo();  // calls D::foo() !?
}

Member method and static member method are entirely different for 2 reasons:

  1. static method doesn't override the virtual functions in base class
  2. Function pointer signature for both the cases are different

When a method is called by an object, shouldn't the member method have higher preference logically ? (Just that C++ allows static method to be called using object, would it be considered as an overridden method ?)

iammilind
  • 62,239
  • 27
  • 150
  • 297

2 Answers2

9

The rule that you are seeing is described in ISO/IEC 14882:2003 7.3.3 [namespace.udecl] / 12 :

When a using-declaration brings names from a base class into a derived class scope, member functions in the derived class override and/or hide member functions with the same name and parameter types in a base class (rather than conflicting).

Without this rule, the function call would be ambiguous.

CB Bailey
  • 648,528
  • 94
  • 608
  • 638
  • Is it applicable for `static` members also ? If yes then why does `static` methods conflict with `virtual` methods ? – iammilind Jun 16 '11 at 06:58
  • @iammilind Because this only applies to the using declaration. – Šimon Tóth Jun 16 '11 at 07:01
  • 2
    @iammilind: `virtual` and `static` don't make any difference at this point because it is just overload resolution that determining which function should be called on your `D` object. – CB Bailey Jun 16 '11 at 07:03
  • 1
    That's the least obvious thing here: there's no reason static methods need to be considered at all when doing non-static resolution, but that's just the way things work. – Eamon Nerbonne Jun 16 '11 at 07:23
  • 2
    @Eamon: it's all a matter of "fragile" base class. The problem stems from the fact that the static method may be invoked from with a `dot`. From this point on, **hiding** is mandatory, otherwise *introducing* `foo` in the base class would potentially break **all** client code. – Matthieu M. Jun 16 '11 at 08:41
1

The issue here is that you can't overload a static method using a non-static method with the same signature.

Now, if you try:

struct D {
  void foo () {}
  static void foo () {}
};

It will trigger an error.

I'm not really sure why in case of using B::foo it is actually silently ignored without triggering an error/warning (at least on GCC 4.5.1).

Šimon Tóth
  • 33,420
  • 18
  • 94
  • 135