On Fri, Mar 24, 2023 at 11:17 AM Andrey Semashev via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
On 3/24/23 18:05, Oleksandr Koval via Std-Proposals wrote:
> Actually, allowing default values can break
> existing code because right now `Enum e{};` always means e = 0, after
> your change the value will be different.

No existing code uses "default:" for marking the default enum value
because currently this syntax is invalid. So this is not a breaking change.

It's a breaking change to the programmer's intuition, though, if they're used to `T t = T();` meaning "zero-initialization" for scalar types.
It certainly interacts with Giuseppe's recent P2782 "Type trait to detect whether a type is trivially value-initializable by zero-filling."
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2782r0.html
Right now that trait is obviously `true` in practice for all integer and enum types, at least on sane platforms; and P2782R0 proposes that it should be formally set in stone for integer and enum types forever.
Aleksej is proposing to make that trait not-true for some (but not all) enum types.

Anyway, that's a game-ending objection to the semantics IMHO; but even syntax-wise, we don't currently use the `default` keyword in this way at all.
    enum E { RED, GREEN, default: BLUE=42, };  // not terribly confusing, but not consistent with the rest of the language
The way C++ does defaults is with an equals sign:
    int foo(int x = 42);  // default argument
    struct S { int x = 42; };  // default initializer
So the right syntax for the proposed semantics might be something like
    enum E : int = 42 { RED, GREEN, BLUE=42, };
except that we want to say `= BLUE` there and we can't because `BLUE` is an unknown identifier; so perhaps
    enum E : int { RED, GREEN, BLUE, E() = BLUE };
except that that syntax already has a meaning (consider what happens if `operator=` is overloaded and constexpr) and is ugly anyway.
Seems to me that this feature would fit in(...to the trash can) with all other proposals around "adding member functions to enum types." What you're doing here is simply adding a non-trivial default constructor to the enum type:
    enum E : int {
        RED, GREEN, BLUE,
        E() : E(BLUE) {}  // C++11 delegating ctor syntax; delegate to the copy ctor which already implicitly exists(*)
    };
(*— or maybe to the ctor from int, which already exists; it depends on what context you think we're in at this point in the source code.)

Rather than adding member functions to enums, maybe it would be more productive to look at ways to
- derive class types from enum types, so that you could inherit the enumerators and then add methods to the class in the usual way
- define value-semantic class types with nested "enumerators" quickly and easily, without involving C-style enum types at all

my $.02,
–Arthur