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