Template to retrieve compile-time enum member from run-time enum member?

Simen Kjærås simen.kjaras at gmail.com
Fri Apr 27 13:39:22 UTC 2018


On Friday, 27 April 2018 at 13:27:45 UTC, Timoses wrote:
> Bumped across another problem : /
>
> ```
> import std.stdio;
>
> enum menum { A, B, C }
>
> void main()
> {
>    foo(menum.A);
> }
>
> void foo(menum e)
> {
>     writeln(instantiateWith!Temp(e));
> }
>
> auto instantiateWith(alias Fn, T)(T x)
>     if (is(T == enum))
> {
>     switch (x)
>     {
>         import std.traits : EnumMembers;
>         static foreach (e; EnumMembers!T)
>             case e:
>                 return Fn!e;
>         default:
>             assert(false);
>     }
> }
>
> template Temp(menum e)
> {
>     struct TempStruct { uint i; };
>     TempStruct Temp;
>
>     shared static this()
>     {
>         static if (e == menum.A)
>             Temp.i = 3;
>     }
>
> }
> ```
>
> now returns:
> source\app.d(25,17): Error: mismatched function return type 
> inference of `TempStruct` and `TempStruct`
> source\app.d(12,33): Error: template instance 
> `app.instantiateWith!(Temp, menum)` error instantiating
> dmd failed with exit code 1.
>
> It's the same return type... so why the error?

That's an unfortunate error message. The problem is TempStruct is 
defined inside the Temp template. In the same way that struct 
Foo(T) {} is different for Foo!int and Foo!string, TempStruct is 
a different type for Temp!(menum.A) and Temp!(menum.B).

The solution is to move TempStruct outside the template:

struct TempStruct { uint i; }

template Temp(menum e)
{
     TempStruct Temp;
     shared static this()
     {
         static if (e == menum.A)
             Temp.i = 3;
     }
}

--
   Simen


More information about the Digitalmars-d-learn mailing list