C++ Logo

std-proposals

Advanced search

Re: [std-proposals] !override

From: Paul Fee <paul.f.fee_at_[hidden]>
Date: Tue, 8 Nov 2022 22:39:40 +0000
On Tue, Nov 8, 2022 at 12:47 AM Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
wrote:

> On Mon, Nov 7, 2022 at 5:57 PM Paul Fee <paul.f.fee_at_[hidden]> wrote:
>
>> Thanks to all for your replies.
>> My only need for this is during refactoring. You've collectively given
>> me enough options to address my issue without additions to C++, so we
>> needn't go further.
>> [...]
>> My suggestion derived from my current use of "final". I often place it
>> on a class (despite core-guidelines C.139) to prove that there are no
>> derived classes. I'm then free to remove redundant use of virtual, which
>> may for example allow the virtual destructor to evaporate, allowing
>> application of the rule-of-zero.
>>
>
> Yes, absolutely. IMO, rule C.139 doesn't have much rationale behind it. In
> *large* codebases (like, industry-size, not hobby-project-size), I think
> it's quite useful to mark leaf classes as `final` (this helps ensure your
> coworkers never introduce "grandchild classes" without *really* thinking
> about it) and even to mark some non-OOP classes as `final` if they're named
> or used in ways that make them easily confusable with OOP classes (here
> `final` means "Don't worry, this isn't a base class").
>
> Another refactor is to mark copy constructors "= delete", to prove they're
>> never used. This allows a redundant user-declared implementation to be
>> removed without fear of impacting behaviour.
>>
>
> Yep. Speaking of refactoring and overload sets, I've found `=delete` quite
> useful for ordinary (if bad-coding-style'd) overload sets too. Suppose we
> have
> (simplified from
> https://quuxplusone.github.io/blog/2020/10/11/overloading-considered-harmful/
> )
>
> void subscribe(Actor*, int, bool = false); // #1
> void subscribe(Actor*, bool = false); // #2
>
> We suspect that overload #1 is unused. We comment it out, and the codebase
> still compiles, so we think it's safe to remove. But by removing it we
> introduced a bug! Somewhere further down in the codebase, we have a
> call-site like this:
> subscribe(p, 42);
> This used to call #1 as the best match; but with #1 eliminated, it will
> happily call #2 instead.
> The "right" way to test whether #1 is unused is not to comment it out, but
> to mark it `=delete`. This makes all its callers ill-formed *without*
> changing the overload resolution, so we can be sure we're seeing all the
> call-sites (where we hope that the set of all call-sites is empty).
>
> HTH,
> Arthur
>

Thanks, that's a great tip. I'll be using "= delete" even more now whilst
refactoring.

Received on 2022-11-08 22:39:52