templates
bearophile
bearophileHUGS at lycos.com
Mon Apr 19 14:20:21 PDT 2010
Steven Schveighoffer:
> What I had in mind was:
>
> struct S
> {
> int foo(int x) { return x * 2; }
> }
>
> struct S2
> {
> int foo(int x) { return x + 2; }
> }
>
> void main()
> {
> S s1;
> S2 s2;
>
> IW[] ws;
>
> ws ~= makeW(s1);
> ws ~= makeW(s2);
>
> assert(ws[0].foo(3) == 6);
> assert(ws[1].foo(3) == 5);
> }
>
> does this help?
A possible solution, this code is just an idea that needs improvements, it's not generic:
struct S1 {
int foo(int x) { return x * 2; }
}
struct S2 {
int foo(int x) { return x + 2; }
}
enum TypeTag { TS1, TS2 }
struct Wrapper {
TypeTag tag;
union {
S1 s1;
S2 s2;
}
int foo(int x) {
final switch(this.tag) {
case TypeTag.TS1: return s1.foo(x);
case TypeTag.TS2: return s2.foo(x);
}
}
}
Wrapper makeW(T)(T s) if (is(T == S1) || is(T == S2)) {
static if (is(T == S1)) {
Wrapper result = Wrapper(TypeTag.TS1);
result.s1 = s;
return result;
} else static if (is(T == S2)) {
Wrapper result = Wrapper(TypeTag.TS2);
result.s2 = s;
return result;
} else
assert(0);
}
void main() {
S1 s1;
S2 s2;
Wrapper[] ws;
ws ~= makeW(s1);
ws ~= makeW(s2);
assert(ws[0].foo(3) == 6);
assert(ws[1].foo(3) == 5);
}
There are several other ways to solve this problem. This version is a bit nicer because it contains no pointer casts.
Languages that have a tagged union (like Cyclone) need quite less code here, but probably D2 can be used to remove some of that code duplication.
Bye,
bearophile
More information about the Digitalmars-d-learn
mailing list