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