A virtual method that must *always* be overridden?

1,275 views
Skip to first unread message

Matthew Woehlke

unread,
Apr 4, 2019, 1:18:56 PM4/4/19
to ISO C++ Standard - Future Proposals
While adding a `virtual Self* clone() = 0` to a class yesterday, I
realized something... why does C++ not have a way to mark a method that
must *always* be overridden? I'm talking about something *more* than a
pure virtual, i.e.:

struct Root
{
virtual Root* foo() bikeshed;
};

struct Derived : Root
{
};

struct MoreDerived : Derived
{
virtual Root* foo();
};

Root x; // okay
Derived y; // error: 'foo' was not overridden
MoreDerived z; // okay

Would this be useful?

--
Matthew

Brian Bi

unread,
Apr 4, 2019, 1:35:51 PM4/4/19
to std-pr...@isocpp.org
How is this different from a pure virtual method?

Since foo() is not overridden in Derived, Derived is an abstract class and cannot be instantiated.

By "must *always* be overridden" I had thought you meant that the definition of Derived would be ill-formed, or something like that. And was going to ask why you would ever want that.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/42fc876e-a4c7-a247-bc7f-632efbe1b28d%40gmail.com.


--
Brian Bi

Jared Grubb

unread,
Apr 4, 2019, 1:38:26 PM4/4/19
to ISO C++ Standard - Future Proposals
I think he wants a *concrete* class that, when used as a base class, has methods that must be overridden.

Jared

On Thursday, April 4, 2019 at 10:35:51 AM UTC-7, Brian Bi wrote:
How is this different from a pure virtual method?

Since foo() is not overridden in Derived, Derived is an abstract class and cannot be instantiated.

By "must *always* be overridden" I had thought you meant that the definition of Derived would be ill-formed, or something like that. And was going to ask why you would ever want that.

On Thu, Apr 4, 2019 at 12:18 PM Matthew Woehlke <mwoehl...@gmail.com> wrote:
While adding a `virtual Self* clone() = 0` to a class yesterday, I
realized something... why does C++ not have a way to mark a method that
must *always* be overridden? I'm talking about something *more* than a
pure virtual, i.e.:

  struct Root
  {
    virtual Root* foo() bikeshed;
  };

  struct Derived : Root
  {
  };

  struct MoreDerived : Derived
  {
    virtual Root* foo();
  };

  Root x; // okay
  Derived y; // error: 'foo' was not overridden
  MoreDerived z; // okay

Would this be useful?

--
Matthew

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-pr...@isocpp.org.


--
Brian Bi

Brian Bi

unread,
Apr 4, 2019, 1:39:50 PM4/4/19
to std-pr...@isocpp.org
Oh I see, I didn't notice that `Root x;` was supposed to compile.

To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.

To post to this group, send email to std-pr...@isocpp.org.


--
Brian Bi
Message has been deleted
Message has been deleted
Message has been deleted
Message has been deleted

Matthew Woehlke

unread,
Apr 5, 2019, 4:13:27 PM4/5/19
to std-pr...@isocpp.org
(Re-send; Google is being obnoxious again...)

On 04/04/2019 13.35, Brian Bi wrote:
> How is this different from a pure virtual method?

...because once *any* class overrides it, that suffices for the whole
hierarchy. What I want is for (use of) *any* derived class to be IFDR if
the method is not overridden.

Consider:

struct A { virtual foo() = 0; };
struct B : A { virtual foo() override; };
struct C : B {};

Right now, I can instantiate a `C`, even though `C` did not override
`foo`. I want something that will let me make that IFDR.

(The motivation, as alluded in the original post, is to prevent mistakes
where not overriding a method is likely an error. For example, if I have
a `clone` method and forget to override it, I unexpectedly have slicing.)

> By "must *always* be overridden" I had thought you meant that the
> definition of Derived would be ill-formed, or something like that.

I specifically *don't* want the definition to be ill-formed. I think
it's plausible that an intermediary might not want to override such a
method. Such an intermediary (as shown in my original example) would be
considered abstract. Just like any class with a pure virtual, you can
derive from it, but trying to directly instantiate it is ill-formed.

An existing pure virtual is abstract *until* it is overridden. What I'm
proposing is a method that (may or may not be initially, but) *becomes*
abstract *unless* it is overridden, and does so persistently.

--
Matthew

Richard Hodges

unread,
Apr 5, 2019, 11:45:47 PM4/5/19
to std-pr...@isocpp.org
On Fri, 5 Apr 2019 at 21:13, Matthew Woehlke <mwoehlk...@gmail.com> wrote:
(Re-send; Google is being obnoxious again...)

On 04/04/2019 13.35, Brian Bi wrote:
> How is this different from a pure virtual method?

...because once *any* class overrides it, that suffices for the whole
hierarchy. What I want is for (use of) *any* derived class to be IFDR if
the method is not overridden.

Is this a common use case? By which I mean common enough to warrant introducing a new keyword along with the resulting increasing complication in teaching the language?

You may have a specific use case that would benefit from such a feature, but (for example) I have never encountered one. 

Unequivocal demonstrations of benefit to the c++ community would go a long way to persuading people to give this idea the time of day.

 

Consider:

  struct A     { virtual foo() = 0; };
  struct B : A { virtual foo() override; };
  struct C : B {};

Right now, I can instantiate a `C`, even though `C` did not override
`foo`. I want something that will let me make that IFDR.

(The motivation, as alluded in the original post, is to prevent mistakes
where not overriding a method is likely an error. For example, if I have
a `clone` method and forget to override it, I unexpectedly have slicing.)

> By "must *always* be overridden" I had thought you meant that the
> definition of Derived would be ill-formed, or something like that.

I specifically *don't* want the definition to be ill-formed. I think
it's plausible that an intermediary might not want to override such a
method. Such an intermediary (as shown in my original example) would be
considered abstract. Just like any class with a pure virtual, you can
derive from it, but trying to directly instantiate it is ill-formed.

An existing pure virtual is abstract *until* it is overridden. What I'm
proposing is a method that (may or may not be initially, but) *becomes*
abstract *unless* it is overridden, and does so persistently.

--
Matthew

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.

Alberto Barbati

unread,
Apr 8, 2019, 4:54:39 AM4/8/19
to ISO C++ Standard - Future Proposals
Il giorno sabato 6 aprile 2019 05:45:47 UTC+2, Richard Hodges ha scritto:


On Fri, 5 Apr 2019 at 21:13, Matthew Woehlke <mwoehl...@gmail.com> wrote:
(Re-send; Google is being obnoxious again...)

On 04/04/2019 13.35, Brian Bi wrote:
> How is this different from a pure virtual method?

...because once *any* class overrides it, that suffices for the whole
hierarchy. What I want is for (use of) *any* derived class to be IFDR if
the method is not overridden.

Is this a common use case? By which I mean common enough to warrant introducing a new keyword along with the resulting increasing complication in teaching the language?

Unfortunately Google rejected the OP's answer about a use case that is actually very common and IMHO compelling: the clone() function.

However, I agree that it's still not important enough for a language feature. But... what about an attribute?

struct BikeShed
{
    [[concrete_classes_must_override]] virtual void f() = 0;
};

Just my two eurocent,
Reply all
Reply to author
Forward
0 new messages