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