それが、かつて言語が機能していた方法です。usingキーワードの前に、1 つのオーバーロードされた関数をオーバーライドすると、それらすべてをオーバーロードする必要がありました。
class bar : public foo
{
public:
bar(void);
~bar(void);
a(int);
a(double d) { foo::a(d); } // add this
}
これは、言語委員会がusing機能を追加するほど人々を悩ませましたが、いくつかの古い習慣はなかなか消えません。そして習慣†には良い議論があります。
James Hopkins が指摘しているように、using を追加することで、プログラマーは、派生クラスが警告なしに、受け入れ可能なシグネチャのリストに foo::a() の将来のオーバーライドを追加するという意図を表明しています。
彼が説明する内容の例を次に示します。
#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;
}
出力は "Derived::Double!" になります。コンパイラは整数引数を double にプロモートするためです。g++ 4.0.1 - Wall は、このプロモーションが発生したことを警告しません。
メソッド Base::f(int) を追加する Base への将来の変更をシミュレートするには、(1) のコメントを外します。このコードは、-Wall と "Derived::Double!" を使用しても警告なしでコンパイルされます。出力のままです。
ここで (2) のコメントを外して、すべての Base::f シグネチャを含めるという Derived プログラマによる決定をシミュレートします。コードは (警告なしで) コンパイルされますが、出力は "Base::Int!" になります。
—
†「習慣を持っている人」を表す英語の単語が思い浮かびません。「中毒」は強すぎます。