Reputation: 1138
I'm in trouble on designing a D app. Maybe my approach is completely wrong, so I come here to you rescue me. Any suggestion, including complete rewrite, is welcome.
I have some templated types:
enum Type : byte { Message='!', Integer='@' }
struct Token (T) {
Type type;
T value;
}
alias Token!string MessageToken;
alias Token!long IntegerToken;
And I need to handle these types generically:
AnyToken genToken(bool cond) {
if (cond)
return MessageToken(Type.Message, "nighly builds");
else
return IntegerToken(Type.Integer, -42);
}
AnyToken a = genToken(true);
AnyToken b = genToken(false);
How do I achieve this effect? Edit: OOP alternatives are welcome too.
Upvotes: 5
Views: 185
Reputation: 78585
If you really need to keep the original structs then you could create a hierarchy of classes that wrap a pointer to a struct and dispatch accordingly.
Upvotes: 2
Reputation: 48196
I'd have used a tagged union myself
struct Token{
Type type;
union{
string str;
long integer;
}
@property string strMessage()in{assert(type==Type.Message)}body{
return str;
}
@property void strMessage(string s){
type=Type.Message;
str=s;
}
@property long intMessage()in{assert(type==Type.Integer)}body{
return integer;
}
@property void intMessage(long l){
type=Type.Integer;
integer=l;
}
}
note that there's no static (compile time) difference between them but it's pretty much the best on can do without inheritance
you can add some extra functions so it looks more like inheritance so you won't need to examine the type field so much outside the struct's functions
Upvotes: 6
Reputation: 6287
You could use std.variant.
I can't imagine another way. In the end they are completely separate types.
Upvotes: 4