On Mon, Jun 28, 2021 at 3:26 AM chuanqi.xcq via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
> I am cleanning some codes with the warning of overloaded virtual functions.
> Here is the introduction for overloaded virtual functions:
> https://stackoverflow.com/questions/18515183/c-overloaded-virtual-function-warning-by-clang
> At first, I thought it is a compiler bug.
> However, I find these words in 9.9.14 N4878,
> "In a using-declarator that does not name a constructor, every declaration named shall be accessible."

It took me a while to understand your example. Eventually I got it:
Class `A` has overloaded public and private constructors, and overloaded public and private `get` methods.
Class `B` can say `using A::A;` just fine. But it can't say `using A::get;`. This feels inconsistent.

However, `using A::A` does something very different from `using A::get`. When you inherit constructors with `using`, you're doing it because constructors are not ordinarily inherited at all. When you `using` the name of an ordinary member function, it's not "to inherit them," because ordinary member functions are already inherited just fine; it's rather because you want to change the access control of the existing names.

In Chuanqi's specific case, the right refactoring is not to use `using` — I mean, to a first approximation, using `using` is never appropriate in modern C++! The right refactoring is to eliminate the combination of overloading and virtual methods. Virtual methods aren't called directly by the client (because Non-Virtual Interface Idiom), so you're in control of these names, so you can give them whatever names you choose.  For example, "virtual void *getByName(char *)" and "virtual void *getByNameAndIndex(char *, int)". Then the names don't collide, so there's no name hiding, so you don't have to work around anything at all.
See also "When Should You Give Two Things the Same Name?" (CppCon 2021), which coincidentally "premieres in 3 hours from now" according to YouTube.