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:
https://godbolt.org/z/M3fhPxhjc
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.
https://godbolt.org/z/cM3PPjKaK
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.
HTH,
Arthur