C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Add inheritance for Enum Class enumerations

From: Marcin Jaczewski <marcinjaczewski86_at_[hidden]>
Date: Sat, 25 Apr 2026 19:38:12 +0200
sob., 25 kwi 2026 o 10:03 Jens Maurer via Std-Proposals
<std-proposals_at_[hidden]> napisał(a):
>
>
>
> On 4/25/26 01:11, Sebastian Wittmeier via Std-Proposals wrote:
> > They could have different underlying representations:
>
> Yes.
>
> > With strong typing the compiler could add an offset for one of the ancestor enum classes.
>
> No, that won't work.
>
>
> If this hypothetical feature is just for re-using enum values
> and allowing conversion from a "base" value to a "derived" enum type,
> then maybe there's some merit hidden here. However, I can't see how
> to make a "Derived*" convert to a "Base*", similar to class derivation.
>
>
> Alternative syntax suggestion:
>
> enum class Derived {
> using enum Base; // import the enumerators here; ugh, semicolon
> NEXT_ENUM = whatever,
> };

or maybe better would simply allow user-defined conversion functions for enums.
Then we could allow conversion from `Base` to `Derived`.


>
> Jens
>
>
> >
> > -----Ursprüngliche Nachricht-----
> > *Von:* Arthur O‘Dwyer via Std-Proposals <std-proposals_at_[hidden]>
> > *Gesendet:* Fr 24.04.2026 23:10
> > *Betreff:* Re: [std-proposals] Add inheritance for Enum Class enumerations
> > *An:* std-proposals_at_[hidden];
> > *CC:* Arthur O‘Dwyer <arthur.j.odwyer_at_[hidden]>;
> > On Fri, Apr 24, 2026 at 4:00 PM Gašper Ažman via Std-Proposals <std-proposals_at_[hidden] <mailto:std-proposals_at_[hidden]>> wrote:
> >
> > Note that `using enum` exists and probably does what you need.
> >
> >
> > I don't think "using enum" does what Andrey wants — because I think Andrey is trying to describe this other common problem instead. This /r/ProgrammingLanguages thread <https://www.reddit.com/r/ProgrammingLanguages/comments/rk1y4u/extending_enums/> calls it "extending enums."
> > Here's some lightly-anonymized code from a real (DNS-related) codebase:
> >
> > enum HttpServerStat {
> > TLS_HANDSHAKES,
> > TLS_HANDSHAKE_ERRORS,
> > TLS_HANDSHAKE_TIMEOUTS,
> > [...]
> > RESPONSE_DROPS,
> > MAX_HTTP_SERVER_STAT_ID
> > };
> >
> > enum HttpStat {
> > // Extends HttpServerStat
> > QUERY_COUNT_HTTP = MAX_HTTP_SERVER_STAT_ID,
> > QUERY_BYTES_HTTP,
> > RESPONSE_COUNT_HTTP,
> > RESPONSE_BYTES_HTTP,
> > [...]
> > MAX_HTTP_STAT_ID
> > };
> >
> > enum ODoHStat {
> > // Extends HttpStat
> > ODOH_QUERY_COUNT = MAX_HTTP_STAT_ID,
> > ODOH_QUERY_BYTES,
> > [...]
> > ODOH_4XX_RESPONSE,
> > MAX_ODOH_STAT_ID
> > };
> >
> > (Sidebar: We had to make some very minor changes to the users of this code for C++20, which tightened restrictions on cross-enum arithmetic and comparison.)
> > The idea is that ODoHStat "extends" HttpStat in the same way that std::partial_ordering "extends" std::strong_ordering. Every value in the domain of HttpStat is also in the domain of ODoHStat (although the reverse is not true).
> > Notice that this is the opposite of what class inheritance means! When a /class/ ODoHStat /derives/ from HttpStat then we say that every object of type ODoHStat is an object of type HttpStat (not the reverse).
> >
> > What we really want to be able to say here is something like
> > enum class ODoHStat : using HttpStat {
> > ODOH_QUERY_COUNT = MAX_HTTP_STAT_ID,
> > ODOH_QUERY_BYTES,
> > [...]
> > ODOH_4XX_RESPONSE,
> > MAX_ODOH_STAT_ID
> > };
> > Again, notice the inappropriateness of "inheritance" syntax here.
> > enum ODoHStat : HttpStat { // NO!
> > Because that syntax already has a meaning for enum declarations: it's "HttpStat is the underlying type of ODoHStat; we guarantee that all values of type ODoHStat will fit into an HttpStat." Which is /*not at all*/ what we mean here; in fact we mean the opposite: here we guarantee that all values of type /HttpStat/ will fit into an /ODoHStat/.
> >
> > This fantasy feature would permit us to use `enum class`, and expose all the enumerators of the "parent" enum as members of the "child", thus:
> > ODoHStat e = ODoHStat::QUERY_COUNT_HTTP;
> > Today, we can't do that. We can either avoid scoped enums altogether, or else we have to write
> > ODoHStat e = static_cast<ODoHStat>(HttpStat::QUERY_COUNT_HTTP);
> >
> > If we got such a facility:
> >
> > (1) We would not want to permit the "child" enum to just start listing new enumerators without an initializer for the first one:
> > enum class ODoHStat : using HttpStat { ODOH_QUERY_COUNT, ODOH_QUERY_BYTES, [...] // NO!
> > because what would they start numbering at — zero? one-more-than-the-parent-enum's-highest-enumerator? std::bit_ceil-of-one-more-than-the-parent-enum's-highest-enumerator? None of these are safe answers. The only safe pattern is as we do in the code above: start where the parent enum tells you to start. Even then, this is super fragile: if we add a new enumerator to HttpStat, that will increment the values of ODoHStat's enumerators too. Arguably the author of ODoHStat knew what they were signing up for when they used this facility?
> >
> > (2) The facility does not seem to permit "multiple inheritance," or if it does, the semantics might be surprising.
> > enum class Fruit { Apple, Grape, Orange };
> > enum class Color { Red, Orange, Yellow };
> > enum class Thing : using Fruit, Color {};
> > // both Thing::Apple and Thing::Red have value zero, right?
> > // does Thing::Orange exist? what is its value?
> >
> > Anyway, I'm sure "extending enums" has been proposed before, but I haven't yet found where. N1513 Improving Enumeration Types <http://www2.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1513.pdf> (2003) sketches several ideas re enums, but not this one.
> >
> > my $.02,
> > –Arthur
> >
> > --
> > Std-Proposals mailing list
> > Std-Proposals_at_[hidden]
> > https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
> >
> >
> >
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2026-04-25 17:38:28