templated type reduction
ag0aep6g via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sat Sep 2 14:27:07 PDT 2017
On 09/02/2017 11:07 PM, EntangledQuanta wrote:
> struct X(T)
> {
> string type = T.stringof;
> T t;
> }
[...]
> void* x = new X!int;
>
> (passed around the program)
>
> switch(x.type)
> {
> case "int" : break;
> }
>
> which is invalid yet perfectly valid! Is there any way to make this work
> legitly in D?
Not with `void*`, I think. `void*` explicitly tells the compiler to
forget anything it knows about the type.
You could make a new type `struct XBase { string type; }` and use
`XBase*` instead of `void*`.
If you're going to `new` the instances anyway, classes could also help:
----
class XBase { string type; }
class X(T) : XBase { T t; }
----
[...]
> note that it is really no different from
>
> struct X(T)
> {
> string type = "asdf";
> T t;
> }
>
> in which we can do
>
> string type = (cast(X!int)x).type; // = asdf
>
> or
>
> string type = (cast(X!float)x).type; // = asdf
>
> but even this is a bit fishy.
I think this is the best you can do with `void*`. Maybe add an assert in
X that checks that the field `type` is always at the same offset (0).
> Heres some code that does the offset hack:
>
>
> struct X(T)
> {
> string type = T.stringof;
> T x;
> }
>
> int main(string[] args)
> {
>
> void* x = new X!int;
>
> int o = (X!float).type.offsetof;
> auto y = *cast(string*)(x + o);
> writeln(y);
> return 0;
> }
I don't think `.offsetof` buys you anything over `(cast(X!int)x).type`.
By the way, `void main()` is valid. You don't need to return 0 or
declare `args` if you don't use them.
More information about the Digitalmars-d-learn
mailing list