Enums with Inline Subclass
Bastiaan Veelo
Bastiaan at Veelo.net
Wed Nov 13 23:32:04 UTC 2019
On Wednesday, 13 November 2019 at 20:46:25 UTC, mark_mcs wrote:
> I spend most of my time in java land but try to sneak in some D
> code whenever possible. One pattern that comes in handy is to
> use Java enums as states in a finite state machine (good for
> XML parsers). Given that D supports enums with custom base
> types, I was curious to see if this pattern would translate.
>
> The code looks like this:
>
>
> interface A
> {
> void process();
> }
>
> enum Test : A
> {
> Value1 = new class A {
> override void process() { writeln("Value1"); }
> },
> Value2 = new class A {
> override void process() { writeln("Value2"); }
> }
> }
>
> void main()
> {
> Test.Value1.process();
> }
>
>
> It's syntactically valid but you get linker errors. Seems the
> compiler doesn't generate the vtable for the inline classes:
>
> undefined reference to `_D3app4Test12__anonclass16__vtblZ'
> undefined reference to `_D3app4Test12__anonclass17__ClassZ
>
> My question is: should this be possible? Is this a grammar bug
> or a codegen bug?
That is some odd code you got there. I would not have expected it
to work. Normally references to objects cannot be stored in an
enum. But if you change the interface into a class, and define
the anonymous classes with a name, then it works:
import std;
class I
{
void process() {}
}
class C : I
{
override void process()
{
writeln("C");
}
}
class D : I
{
override void process()
{
writeln("D");
}
}
// enum e = new C; // Unable to initialize enum with class or
pointer to struct. Use static const variable instead.
enum e3 : I
{
val1 = new C,
val2 = new D,
val3 = new class I
{
override void process()
{
writeln("E");
}
}
};
void main()
{
e3.val1.process;
e3.val2.process;
// e3.val3.process; // link error
}
Bastiaan.
More information about the Digitalmars-d
mailing list