Зарисовка на полях:
Есть enum. Ну, все знают что такое enum -- перечисляемый тип, младший брат алгебраического типа данных.
В D у enum'a есть понятие базового типа. Если у двух типов-енумов базовый тип одинаков, то их можно сравнивать, а вот присваивать нельзя. Пример:
enum A : int {A, B, C} // int -- базовый тип
enum B : int {A, B, C} // но его можно было и не писать, ибо int базовый тип по умолчанию
A a; // a == A.a -- по умолчанию инициализируется первым значением
B b;
a == b; // можно
a = b; // нельзя
Причем в переменной типа enum (в примере - a, либо b) не содержится каких-либо дополнительных тэгов. То есть там по честному просто int Будет лежать (или какой там у нас базовый тип). Никакого дополнительного оверхеда.
В качестве базового типа может быть любой тип данных. лишь бы там была определена операция <. То есть мы можем определить какой-нибудь свой тип (структуру, класс) и подсунуть его в виде базового типа данных в enum.
Ну, например можно строку:
enum Strings : string {A = "A", B="B"}
Strings s = Strings.B;
Как и все остальное в D у меня здешние enum'ы не вызывают wow-эффекта. Например искаропки у enum'a нельзя на этапе компиляции (вроде бы) и на этапе исполнения узнать какие у него вообще есть компоненты-константы. По крайней мере нет простого способа это узнать. С другой стороны, через свой базовый тип это делается довольно таки просто.
В общем, смешанные чувства, как и от всего остального в D. И, возможно, это и есть правильно. (wow-эффект всегда настораживает, по крайней мере лично меня).