That is the way the language used to work. Prior to the using keyword, if you overrode one overloaded function, you had to overload them all:
class bar : public foo
{
public:
bar(void);
~bar(void);
a(int);
a(double d) { foo::a(d); } // add this
}
This annoyed enough people that the language committee added the using feature, but some old habits die hard; and the habitués† have a good argument.
As James Hopkins points out, by adding using, the programmer is expressing the intention that the derived class will, without warning, add any future overrides of foo::a() to its list of acceptable signatures.
Here is an example of what he describes:
#include <iostream>
class Base {
public:
virtual void f(double){ std::cout << "Base::Double!" << std::endl; }
// virtual void f(int) { std::cout << "Base::Int!" << std::endl; } // (1)
virtual ~Base() {}
};
class Derived : public Base {
public:
// using Base::f; // (2)
void f(double) { std::cout << "Derived::Double!" << std::endl; }
};
int main(int, char **) {
Derived d;
d.f(21);
return 0;
}
The output will be "Derived::Double!" because the compiler will promote the integer argument to a double. g++ 4.0.1 -Wall will not warn that this promotion occurred.
Uncomment (1) to simulate a future change to Base adding the method Base::f(int). The code compiles, again without warning even with -Wall, and "Derived::Double!" remains the output.
Now uncomment (2) to simulate a decision by the Derived programmer to include all Base::f signatures. The code compiles (without warnings), but the output is now "Base::Int!".
—
† I cannot think of an English word for "those who have the habit" and "addicted" is much too strong.
a
inbar
... – Maitland