C++ Logo

std-proposals

Advanced search

Re: Should every declaration that using-declarator declared should be accessible?

From: Jason McKesson <jmckesson_at_[hidden]>
Date: Mon, 28 Jun 2021 22:55:03 -0400
On Mon, Jun 28, 2021 at 10:24 PM chuanqi.xcq via Std-Proposals
<std-proposals_at_[hidden]> wrote:
>
> Hi Artuhr,
>
> > 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.
>
> Yeah, it's my main point. It looks inconsistent.
>
> > 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++!
>
> May I ask what's the reason to refuse ** using **? It's my first time to hear it.

`using` in this context is used to make names accessible when they
wouldn't otherwise be accessible. So the question is why you want to
make a name accessible when it wouldn't be.

This makes `using` of this sort something of a code smell; it suggests
that you're doing something you ought not be doing. Like hiding
virtual functions.

> > 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.
>
> It looks like we could only do more aggressive refactoring. OK, maybe it's the right solution even it is harder.
>
> > See also "When Should You Give Two Things the Same Name?" (CppCon 2021), which coincidentally "premieres in 3 hours from now" according to YouTube.
>
> Thanks for sharing!
>
> ---
>
> Finally, I want to discuss that if the control of `using` is too coarsed grained.
> Since `using A::foo` declares all of names foo in A.
> But what if we want to declare only one of them?
> I understand people may argue that the user should rewrite the code to avoid same name problem.
> However, I think that member functions with the same name is fine due to the existence of overloading.
> Then the ability to declare one of the functions would be beneficial in that case.
> The grammer may be:
> ```
> using A::foo(int, int);
> ```

Member functions with the same name are conceptually fine. Member
functions that are *different* but have the same name are not fine.

Why would you want to make one overload of a function available and
*not* the other overload? What is your reasoning for naming these
functions the same?

Basically, I'm questioning the reason why the code you're trying to
make work is code that *ought* to work. I don't think we should add
language features to support bad coding practices.

Received on 2021-06-28 21:55:19